0

I'm analyzing an obfuscated code which splits its code into multiple blocks seperated by many, many unconditional jmps. Here is a picture of what the obfuscation looks like:

code separated by jmps:

I wrote an IDAPython algorithm for this a few weeks ago, but it misplaces labels and does not place code in the correct location for most larger functions. I could not get it to work in the end.

    visted_blocks = list()

f = open("myfile.txt", "w+")



def RemoveJumps(FuncAddress):
  while 1:

    if FuncAddress in visted_blocks:
        return
        
    mnem = idc.GetMnem(FuncAddress)

    if mnem == 'nop':
        FuncAddress = idc.next_head(FuncAddress, -1)
        continue

    if len(list(CodeRefsTo(FuncAddress, 0))) > 0:
        if FuncAddress in visted_blocks:
          return
    
        visted_blocks.append(FuncAddress)
        f.write("loc_%02X: \n" % FuncAddress)

    if len(mnem) == 0 or mnem == 'retn' or mnem == 'int':
        return

    if mnem[0] == 'j':
        # ^if this is a jump/branch
        JmpOperand = get_operand_value(FuncAddress, 0)

        if mnem == 'jmp':
            visted_blocks.append(FuncAddress)
            FuncAddress = JmpOperand # advance to next code
            continue 

        else:     
            # ^else it is a branch, explore recursively
            visted_blocks.append(FuncAddress)
            f.write("   %s \n" % idc.GetDisasm(FuncAddress))
            RemoveJumps(idc.next_head(FuncAddress, -1))
            FuncAddress = JmpOperand # advance to next code
            continue
    else:
        # ^default condition, just print the instruction
        OpHex(FuncAddress, -1)
        f.write("   %s \n" % idc.GetDisasm(FuncAddress))
        FuncAddress = idc.next_head(FuncAddress, -1)

myFuncAddress = 0x774D8
RemoveJumps(myFuncAddress)
f.close()

My script recursively explores every code path, prints the code, and jumps to the next block while omitting the jmp instruction when an unconditional jmp is encountered, and the destination block has no other cross references. This works perfectly well on small functions, however it fails on most other functions. I spent many hours trying to fix the issues when I used my script on larger functions but I could not get it to work. I would like to know about better methods for connecting basic blocks separated by unconditional jumps in a function. In the end, I want to be able to have a disassembly graph that is easily readable.

How can I stitch together those blocks?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.