Re: [DynInst_API:] Basic Blocks and Register Access
Dear Bill, This seems unusual, and suggests that there's some memory corruption going on somewhere. Any chance you can run this under valgrind and send me the results? sure, the following provides the valgrind --leak-check=full dump of the following code snippet: --- ... BPatch_Vector funcs; BPatch_function *func_lib; BPatch_image* img; img = app->getImage(); /* look for the predefined library function 'prolog' */ funcs.clear(); img->findFunction("pfunc_epilog", funcs); func_lib = funcs[0]; /* no arguments required for function 'pprolog' */ std::vector args; BPatch_funcCallExpr func_instr(*func_lib, args); SnippetPtr snippet = PatchAPI::convert(func_instr); if(!snippet) { std::cout << "[ERROR] could not create snippet" << std::endl; exit(-1); } Point p* = mgr->findPoint(Location::Block(block), Point::BlockEntry, true) /* SEGFAULT: the following results in a SEGFAULT*/ InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(), snippet, p); --- Valgrind Dump: --- ... ==19356== Invalid read of size 4 ==19356==at 0x45B1EF3: func_instance::obj() const (in /usr/lib/libdyninstAPI.so.8.1.2) ==19356==by 0x45625C1: registerSpace::actualRegSpace(instPoint*) (in /usr/lib/libdyninstAPI.so.8.1.2) ==19356==by 0x454BD59: AstNode::generate(Dyninst::PatchAPI::Point*, Dyninst::Buffer&) (in /usr/lib/libdyninstAPI.so.8.1.2) ==19356== *by 0x408EE2E: Dyninst::PatchAPI::PatchModifier::insert(Dyninst::PatchAPI::PatchObject*, boost::shared_ptr, Dyninst::PatchAPI::Point*) (PatchModifier.C:188)* ==19356==by 0x8052CDD: binedit::instrument_epilog(void*, unsigned char*, unsigned int, unsigned int, Dyninst::PatchAPI::PatchBlock*) (binedit.cpp:1096) ==19356==by 0x804F5A0: binedit::stack_protect_func(BPatch_function*) (binedit.cpp:398) ==19356==by 0x804F13D: binedit::stack_protect() (binedit.cpp:273) ==19356==by 0x805859A: perform_operation(binedit*, unsigned int, std::string, std::string) (main.cpp:63) ==19356==by 0x8058E6F: main (main.cpp:277) ==19356== Address 0xf8 is not stack'd, malloc'd or (recently) free'd ==19356== ==19356== ==19356== *Process terminating with default action of signal 11 (SIGSEGV): dumping core* ==19356== *Access not within mapped region at address 0xF8* ==19356==at 0x45B1EF3: func_instance::obj() const (in /usr/lib/libdyninstAPI.so.8.1.2) ==19356==by 0x45625C1: registerSpace::actualRegSpace(instPoint*) (in /usr/lib/libdyninstAPI.so.8.1.2) ==19356==by 0x454BD59: AstNode::generate(Dyninst::PatchAPI::Point*, Dyninst::Buffer&) (in /usr/lib/libdyninstAPI.so.8.1.2) ==19356== *by 0x408EE2E: Dyninst::PatchAPI::PatchModifier::insert(Dyninst::PatchAPI::PatchObject*, boost::shared_ptr, Dyninst::PatchAPI::Point*) (PatchModifier.C:188)* ==19356==by 0x8052CDD: binedit::instrument_epilog(void*, unsigned char*, unsigned int, unsigned int, Dyninst::PatchAPI::PatchBlock*) (binedit.cpp:1096) ==19356==by 0x804F5A0: binedit::stack_protect_func(BPatch_function*) (binedit.cpp:398) ==19356==by 0x804F13D: binedit::stack_protect() (binedit.cpp:273) ==19356==by 0x805859A: perform_operation(binedit*, unsigned int, std::string, std::string) (main.cpp:63) ==19356==by 0x8058E6F: main (main.cpp:277) ==19356== If you believe this happened as a result of a stack ==19356== overflow in your program's main thread (unlikely but ==19356== possible), you can try to increase the size of the ==19356== main thread stack using the --main-stacksize= flag. ==19356== The main thread stack size used in this run was 8388608. --- I hope this provides some useful information to you. FYI: I have tried to use not only the insertion varian presented above, using a predefined point, but also the variant without provisioning of any points of the basic block (see short code snippet at the bottom) - since this should be handled by the PatchModifier::insert function, as far as I understood. Nevertheless, I get the same result as above: --- InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(), snippet, NULL); --- Best regards, Sergej ___ Dyninst-api mailing list Dyninst-api@cs.wisc.edu https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
Re: [DynInst_API:] Basic Blocks and Register Access
On 04/28/2014 05:37 PM, Sergej Proskurin wrote: Dear Bill, When you say this crashes with a segfault at the point of insertion, do you mean the mutator crashes when inserting the code, or the mutatee crashes when executing it? In either case, a stack trace will be helpful; in the latter case if you're running the mutatee under Dyninst (rather than as a rewritten binary) setting DYNINST_DEBUG_CRASH=core and enabling core files will get you a mutatee stack trace and core dump. Also, all of the safety operations that Dyninst performs (register saving, stack alignment, etc) will be absent if you're inserting these calls with PatchAPI directly. Unless that's explicitly desirable, or you're replacing our code generation with something that produces more optimized snippets, there's not a lot of benefit to working at the PatchAPI level. sta At the point of the crash, the mutator crashes - not the mutatee, making the environment variable DYNINST_DEBUG_CRASH obsolete at this point. Dmesg, however, reports the following error: --- [93133.621503] BinEditor[3863]: segfault at 109 ip b72c0ef3 sp bf811390 error 4 in libdyninstAPI.so.8.1.2[b7139000+27d000] --- The provided stack trace is: --- ... Program received signal SIGSEGV, Segmentation fault. 0xb7b88ef3 in func_instance::obj() const () from /usr/lib/libdyninstAPI.so.8.1 (gdb) bt #0 0xb7b88ef3 in func_instance::obj() const () from /usr/lib/libdyninstAPI.so.8.1 #1 0xb7b88f2b in func_instance::proc() const () from /usr/lib/libdyninstAPI.so.8.1 #2 0xb7b8a4aa in func_instance::blockEntryPoint(block_instance*, bool) () from /usr/lib/libdyninstAPI.so.8.1 #3 0xb7b4203b in instPoint::blockEntry(func_instance*, block_instance*) () from /usr/lib/libdyninstAPI.so.8.1 #4 0xb7b08f94 in BPatch_basicBlock::findEntryPoint() () from /usr/lib/libdyninstAPI.so.8.1 #5 0x0805285b in binedit::instrument_epilog (this=0x808c028, addr=0x804850a, bytes=0xbfffee63 "\213E\004[9\330\017\204\005", new_nbytes=17, nbytes=1, block=0x87c56c8) at ../src/binedit.cpp:1036 #6 0x0804f3a9 in binedit::stack_protect_func (this=0x808c028, func=0x87c4138) at ../src/binedit.cpp:398 #7 0x0804ef3e in binedit::stack_protect (this=0x808c028) at ../src/binedit.cpp:273 #8 0x08057b23 in perform_operation (editor=0x808c028, operation=2, func1=..., func2=...) at ../src/main.cpp:63 #9 0x080583f8 in main (argc=13, argv=0xb074) at ../src/main.cpp:277 --- The problem here is that the PatchAPI is surprisingly not able to find a PatchAPI::Point*. And since PatchModifier::insert function cannot access a valid point the process crashes: --- /* this does not find a valid point within the block of any type (entry, exit, during) */ Point* point = mgr->findPoint(Location::Block(block), Point::BlockTypes, true); --- This seems unusual, and suggests that there's some memory corruption going on somewhere. Any chance you can run this under valgrind and send me the results? Dyninst allows access to original register values (through the BPatch interface). It allows instruction replacement through the PatchAPI interface, which would allow bit-twiddling of this sort. The higher a level of abstraction you can express the change at, the more likely it is that we can do the right thing (or a close approximation thereof)--are you trying to replace one variable with another? Change how a variable is referenced? Compensate for changes elsewhere in the code? Exaclty: I am trying to compensate changes of already inserted code: My implementation increases the stack frame, which is the reason why I have to adjust all addresses referenced through the %esp register. There's code in Dyninst that transforms IP-relative memory accesses to account for code relocation; you might be able to borrow/modify/extend that to transform stack references. If you want a working example of instruction replacement through PatchAPI, I'd take a look at Mike Lam's CRAFT tool, available on SourceForge here: http://sourceforge.net/projects/crafthpc/ It's replacing every double-precision instruction in a program with code to shadow the calculation in single-precision and evaluate the error introduced by that replacement; if you strip out the evaluation portion of that, the shadow machinery should give you a pretty good idea of where to start with register manipulation. But, as per above, there may be an easier way to do whatever it is you're aiming for. Thanks for the hint. I have already had a closer look into Mike Lam's CRAFT tool - but unfortunately did not find a solution to my issue, yet. Best regards, Sergej -- --bw Bill Williams Paradyn Project b...@cs.wisc.edu ___ Dyninst-api mailing list Dyninst-api@cs.wisc.edu https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
Re: [DynInst_API:] Basic Blocks and Register Access
Dear Bill, When you say this crashes with a segfault at the point of insertion, do you mean the mutator crashes when inserting the code, or the mutatee crashes when executing it? In either case, a stack trace will be helpful; in the latter case if you're running the mutatee under Dyninst (rather than as a rewritten binary) setting DYNINST_DEBUG_CRASH=core and enabling core files will get you a mutatee stack trace and core dump. Also, all of the safety operations that Dyninst performs (register saving, stack alignment, etc) will be absent if you're inserting these calls with PatchAPI directly. Unless that's explicitly desirable, or you're replacing our code generation with something that produces more optimized snippets, there's not a lot of benefit to working at the PatchAPI level. sta At the point of the crash, the mutator crashes - not the mutatee, making the environment variable DYNINST_DEBUG_CRASH obsolete at this point. Dmesg, however, reports the following error: --- [93133.621503] BinEditor[3863]: segfault at 109 ip b72c0ef3 sp bf811390 error 4 in libdyninstAPI.so.8.1.2[b7139000+27d000] --- The provided stack trace is: --- ... Program received signal SIGSEGV, Segmentation fault. 0xb7b88ef3 in func_instance::obj() const () from /usr/lib/libdyninstAPI.so.8.1 (gdb) bt #0 0xb7b88ef3 in func_instance::obj() const () from /usr/lib/libdyninstAPI.so.8.1 #1 0xb7b88f2b in func_instance::proc() const () from /usr/lib/libdyninstAPI.so.8.1 #2 0xb7b8a4aa in func_instance::blockEntryPoint(block_instance*, bool) () from /usr/lib/libdyninstAPI.so.8.1 #3 0xb7b4203b in instPoint::blockEntry(func_instance*, block_instance*) () from /usr/lib/libdyninstAPI.so.8.1 #4 0xb7b08f94 in BPatch_basicBlock::findEntryPoint() () from /usr/lib/libdyninstAPI.so.8.1 #5 0x0805285b in binedit::instrument_epilog (this=0x808c028, addr=0x804850a, bytes=0xbfffee63 "\213E\004[9\330\017\204\005", new_nbytes=17, nbytes=1, block=0x87c56c8) at ../src/binedit.cpp:1036 #6 0x0804f3a9 in binedit::stack_protect_func (this=0x808c028, func=0x87c4138) at ../src/binedit.cpp:398 #7 0x0804ef3e in binedit::stack_protect (this=0x808c028) at ../src/binedit.cpp:273 #8 0x08057b23 in perform_operation (editor=0x808c028, operation=2, func1=..., func2=...) at ../src/main.cpp:63 #9 0x080583f8 in main (argc=13, argv=0xb074) at ../src/main.cpp:277 --- The problem here is that the PatchAPI is surprisingly not able to find a PatchAPI::Point*. And since PatchModifier::insert function cannot access a valid point the process crashes: --- /* this does not find a valid point within the block of any type (entry, exit, during) */ Point* point = mgr->findPoint(Location::Block(block), Point::BlockTypes, true); --- Dyninst allows access to original register values (through the BPatch interface). It allows instruction replacement through the PatchAPI interface, which would allow bit-twiddling of this sort. The higher a level of abstraction you can express the change at, the more likely it is that we can do the right thing (or a close approximation thereof)--are you trying to replace one variable with another? Change how a variable is referenced? Compensate for changes elsewhere in the code? Exaclty: I am trying to compensate changes of already inserted code: My implementation increases the stack frame, which is the reason why I have to adjust all addresses referenced through the %esp register. If you want a working example of instruction replacement through PatchAPI, I'd take a look at Mike Lam's CRAFT tool, available on SourceForge here: http://sourceforge.net/projects/crafthpc/ It's replacing every double-precision instruction in a program with code to shadow the calculation in single-precision and evaluate the error introduced by that replacement; if you strip out the evaluation portion of that, the shadow machinery should give you a pretty good idea of where to start with register manipulation. But, as per above, there may be an easier way to do whatever it is you're aiming for. Thanks for the hint. I have already had a closer look into Mike Lam's CRAFT tool - but unfortunately did not find a solution to my issue, yet. Best regards, Sergej -- Sometimes the problem is to discover what the problem is. [Gordon Glegg, The Design of Design] ___ Dyninst-api mailing list Dyninst-api@cs.wisc.edu https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
Re: [DynInst_API:] Basic Blocks and Register Access
On 04/26/2014 03:28 PM, Sergej Proskurin wrote: Hello, Within my current implementation, I am able to split and inject basic blocks on the basis of PatchAPI. The newly created and injected basic blocks are currently filled with raw bytes, as stated within the following: InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(), bytes, nbytes); This method of code injection works fine. However, since it is possible to convert BPatch_snippets into PatchAPI::Snippets, I thought it might as well be possible to use predefined library functions to be instumented into the binary into the specified basic block. The following shows an idea of what I inteded to do: --- ... BPatch_Vector funcs; BPatch_function *func_lib; BPatch_image* img; img = app->getImage(); /* look for the predefined library function 'prolog' */ funcs.clear(); img->findFunction("pprolog", funcs); func_lib = funcs[0]; /* no arguments required for function 'pprolog' */ std::vector args; BPatch_funcCallExpr func_instr(*func_lib, args); SnippetPtr snippet = PatchAPI::convert(func_instr); ... /* SEGFAULT: Here, I am not quite sure how to get the right point of the newly created (empty) basic block */ InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(), snippet, point); ... --- Unfortunately, this kind of implementation crashed with a Segfault at the point of insertion. Which might be the result of the fact that I don't know exactly how to find an entry point of the type PatchAPI::Point* to the empty basic block. Any help would be appreciated at this point. When you say this crashes with a segfault at the point of insertion, do you mean the mutator crashes when inserting the code, or the mutatee crashes when executing it? In either case, a stack trace will be helpful; in the latter case if you're running the mutatee under Dyninst (rather than as a rewritten binary) setting DYNINST_DEBUG_CRASH=core and enabling core files will get you a mutatee stack trace and core dump. Also, all of the safety operations that Dyninst performs (register saving, stack alignment, etc) will be absent if you're inserting these calls with PatchAPI directly. Unless that's explicitly desirable, or you're replacing our code generation with something that produces more optimized snippets, there's not a lot of benefit to working at the PatchAPI level. My second question aims at the use of registers: Is it possible to change the registers of individual instructions with help of Dynsinst? The following should explain my idea: --- changing registers from: mov edx, [esp+0x18] e.g into: mov edx, [ebp-0x8] --- My question is: is it possible to use high level constructs of DyninstAPI to make these kind of adjustments or is it easier to work on the level of raw bytes instead? Until now, I was not very successfull in working with registers with help of DyninstAPI. I would really appreciate it if someone could provide me a hint how to correctly access the registers. Dyninst allows access to original register values (through the BPatch interface). It allows instruction replacement through the PatchAPI interface, which would allow bit-twiddling of this sort. The higher a level of abstraction you can express the change at, the more likely it is that we can do the right thing (or a close approximation thereof)--are you trying to replace one variable with another? Change how a variable is referenced? Compensate for changes elsewhere in the code? If you want a working example of instruction replacement through PatchAPI, I'd take a look at Mike Lam's CRAFT tool, available on SourceForge here: http://sourceforge.net/projects/crafthpc/ It's replacing every double-precision instruction in a program with code to shadow the calculation in single-precision and evaluate the error introduced by that replacement; if you strip out the evaluation portion of that, the shadow machinery should give you a pretty good idea of where to start with register manipulation. But, as per above, there may be an easier way to do whatever it is you're aiming for. --bw Thank you very much in advance. Best regards, Sergej -- --bw Bill Williams Paradyn Project b...@cs.wisc.edu ___ Dyninst-api mailing list Dyninst-api@cs.wisc.edu https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api
[DynInst_API:] Basic Blocks and Register Access
Hello, Within my current implementation, I am able to split and inject basic blocks on the basis of PatchAPI. The newly created and injected basic blocks are currently filled with raw bytes, as stated within the following: InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(), bytes, nbytes); This method of code injection works fine. However, since it is possible to convert BPatch_snippets into PatchAPI::Snippets, I thought it might as well be possible to use predefined library functions to be instumented into the binary into the specified basic block. The following shows an idea of what I inteded to do: --- ... BPatch_Vector funcs; BPatch_function *func_lib; BPatch_image* img; img = app->getImage(); /* look for the predefined library function 'prolog' */ funcs.clear(); img->findFunction("pprolog", funcs); func_lib = funcs[0]; /* no arguments required for function 'pprolog' */ std::vector args; BPatch_funcCallExpr func_instr(*func_lib, args); SnippetPtr snippet = PatchAPI::convert(func_instr); ... /* SEGFAULT: Here, I am not quite sure how to get the right point of the newly created (empty) basic block */ InsertedCode::Ptr icode = PatchModifier::insert(post_block->object(), snippet, point); ... --- Unfortunately, this kind of implementation crashed with a Segfault at the point of insertion. Which might be the result of the fact that I don't know exactly how to find an entry point of the type PatchAPI::Point* to the empty basic block. Any help would be appreciated at this point. My second question aims at the use of registers: Is it possible to change the registers of individual instructions with help of Dynsinst? The following should explain my idea: --- changing registers from: mov edx, [esp+0x18] e.g into: mov edx, [ebp-0x8] --- My question is: is it possible to use high level constructs of DyninstAPI to make these kind of adjustments or is it easier to work on the level of raw bytes instead? Until now, I was not very successfull in working with registers with help of DyninstAPI. I would really appreciate it if someone could provide me a hint how to correctly access the registers. Thank you very much in advance. Best regards, Sergej -- Sometimes the problem is to discover what the problem is. [Gordon Glegg, The Design of Design] ___ Dyninst-api mailing list Dyninst-api@cs.wisc.edu https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api