Re: [DynInst_API:] Wrong memory write size?


Date: Wed, 20 Jul 2016 05:07:24 +0200
From: Frederik Peukert <fredi5555@xxxxxx>
Subject: Re: [DynInst_API:] Wrong memory write size?

John,

 

Thank you so much for your help.

 

-- Fredi

 

Von: John Detter [mailto:jdetter@xxxxxxxx]
Gesendet: Dienstag, 19. Juli 2016 21:49
An: Frederik Peukert <fredi5555@xxxxxx>
Cc: dyninst-api@xxxxxxxxxxx
Betreff: Re: AW: [DynInst_API:] Wrong memory write size?

 

Fredi,

To give you some closure on this, we decided that the function name is very misleading. So we have decided for release 9.3.0 we will add a new function that implements the behavior that is true to the documentation. The current function will be deprecated and potentially removed during the next major release (10.X.X).

For now, if you want to get the correct behavior, you will have to call instruction->getOperands() and then from there use operand->writesMemory() to check to see if the operand writes to memory. Then you can use operand->getValue() to get the _expression_ for that operand and get the size of the _expression_.

I have modified the source you sent me to implement the correct behavior.

If you have any more questions let me know,

-- John

Sample output:

[detter@localhost fredi]$ ./reproducer
push RBP, RSP
mov RBP, RSP
mov [RBP + ffffffffffffffff], 41
        mem write 1
mov EAX, 0
pop RBP, RSP
ret near [RSP]

Sample code:

#include <BPatch.h>
#include <BPatch_function.h>
#include <BPatch_flowGraph.h>
#include <Instruction.h>

#include <iostream>

using namespace Dyninst;
using namespace Dyninst::InstructionAPI;

int main(int argc, const char** argv)
{
    BPatch bpatch;
    BPatch_addressSpace *app = bpatch.openBinary("MUTATEE", true);
    BPatch_image *appImage = app->getImage();

    BPatch_Vector<BPatch_function *> functions;
    appImage->findFunction("main", functions);

    BPatch_function* f = functions[0];
    BPatch_flowGraph* fg = f->getCFG();

    std::set<BPatch_basicBlock *> blocks;
    fg->getAllBasicBlocks(blocks);

    for(auto bb_iter = blocks.begin(); bb_iter != blocks.end(); ++bb_iter)
    {
        std::vector<InstructionAPI::Instruction::Ptr> insns;
        (*bb_iter)->getInstructions(insns);

        for(auto ins_iter = insns.begin(); ins_iter != insns.end(); ++ins_iter)
        {
            boost::shared_ptr<Instruction> insn = *ins_iter;
            std::cout << insn->format() << std::endl;

            if(insn->writesMemory())
            {
                std::vector<InstructionAPI::Operand> operands;
                insn->getOperands(operands);

                for(auto oper_iter = operands.begin();
                        oper_iter != operands.end();oper_iter++)
                {
                    InstructionAPI::Operand oper = *oper_iter;
                    if(oper.writesMemory())
                        std::cout << "\tmem write " << oper.getValue()->size() << std::endl;
                }
            }
        }
    }

    BPatch_binaryEdit *appBin = dynamic_cast<BPatch_binaryEdit *>(app);
    appBin->writeFile("MUTATEE_PATCHED");

    return 0;
}

MUTATEE:

int main(void)
{
   char x = 'A';
   return 0;
}

On 7/14/2016 5:21 PM, Frederik Peukert wrote:

John,

 

Thank you for looking into my issue.

My GCC version is 4.8.4.

Since I am new to Dyninst, It might be only an understanding issue.

 

Thanks.

 

--Fredi

 

 

Von: John Detter [mailto:jdetter@xxxxxxxx]
Gesendet: Donnerstag, 14. Juli 2016 20:17
An: Frederik Peukert <fredi5555@xxxxxx>
Cc: dyninst-api@xxxxxxxxxxx
Betreff: Re: [DynInst_API:] Wrong memory write size?

 

Fredi,

 

Could you provide me with your GCC version? I'm looking into your issue now.

Sorry for the long wait,

 

-- John

 

On 7/10/2016 5:10 AM, Frederik Peukert wrote:

Hi all,

 

I use getMemoryWriteOperands() to get the _expression_ of Operands that write to memory and size() to get the actual size of the write. However, it always returns 4 byte, even if I write a single byte (char) like in the following program.

 

int main(void) {

   char x = 'A';

   return 0;

}

 

Even gdb disassembles it to a byte sized write: “mov BYTE PTR [ebp-0x1], 0x41”.

I know that EBP is a 4 byte register, but a 4 byte write would just overwrite the variable next to “x” (at least if layout is not 4 byte aligned). Tell me if I am wrong.

I am using a 32-Bit Linux mint (vmware) and Dyninst 9.2.0.

 

Relevant code:

 

int main(int argc, const char** argv) {

                BPatch bpatch;

                BPatch_addressSpace *app = bpatch.openBinary(“MUTATEE”, true);  

                BPatch_image *appImage = app->getImage();

 

                BPatch_Vector<BPatch_function *> functions;

                appImage->findFunction("main", functions);

 

                BPatch_function* f = functions[0];

                BPatch_flowGraph* fg = f->getCFG();

 

                std::set<BPatch_basicBlock *> blocks;

                fg->getAllBasicBlocks(blocks);

 

                for(auto bb_iter = blocks.begin(); bb_iter != blocks.end(); ++bb_iter){

                                std::vector<Instruction::Ptr> insns;

                                (*bb_iter)->getInstructions(insns);

                                for(auto ins_iter = insns.begin(); ins_iter != insns.end(); ++ins_iter){

                                                cout << (*ins_iter)->format() << endl;

                                                if((*ins_iter)->writesMemory()){

                                                                std::set<_expression_::Ptr> memAccessors;

                                                                (*ins_iter)->getMemoryWriteOperands(memAccessors);

                                                                if (memAccessors.size())

                                                                {

                                                                                for(auto it = memAccessors.begin(); it != memAccessors.end(); ++it)

                                                                                {

                                                                                                std::cout << "\tmem write (size: " << (*it)->size() << ")" << endl;;

                                                                                }

                                                                }

                                                }

                                }

                }

BPatch_binaryEdit *appBin = dynamic_cast<BPatch_binaryEdit *>(app);

                appBin->writeFile(“MUTATEE_PATCHED”);

 

                return 0;

}

 

Thanks!

 

--Fredi




_______________________________________________
Dyninst-api mailing list
Dyninst-api@xxxxxxxxxxx
https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api

 

 

[← Prev in Thread] Current Thread [Next in Thread→]