Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining register values when using objdump

So I'm trying to use the objdump utility to build a Control Flow Graph from assembly, and I'm running into a problem. Basically, whenever a branch occurs and the target address is relative I'm not sure how to know where the next basic block starts. I'm not sure if I'm being clear, so I'll add an example. Say my program is going through the objdump output, and has recorded the starting address for the first basic block. It then hits a jump command that uses relative addressing to point to the proper address to jump to. I know that the end of my first basic block occurs right there, but how do I go about getting the right address for the beginning of the next basic block? Any guidance anyone can provide would be greatly appreciated, I'm an x86 novice at best and I've been banging my head against this for the past week.

like image 440
Sam Avatar asked Nov 30 '10 03:11

Sam


1 Answers

Assuming I understand the question, maybe this will get you started. Relative jumps are pc based.

d: eb 04 jmp 13 

0xEB is the opcode for a relative jump based on an 8 bit immediate. The address of the instruction is in the objdump output, in this case d or 0xD. it is a two byte instruction (x86 is variable length). it tells you in the output what the destination address is, in this case jmp 13. So looking for the line in the objdump output that starts with 13 and a colon is the beginning of that next chunk of code.

To understand how that address is computed. The pc is at 0xD when it starts to fetch the instruction, it takes two bytes, so the pc is at 0xD+2 = 0xF when it is ready to execute this instruction. The offset is 0x4 so 0xF+0x4 = 0x13 the destination address.

20: 75 ed jne f

Same goes for backwards. pc plus number of bytes = 0x20+2 = 0x22. 0xED is a signed number and is negative so sign extend 0xED to 0xFFFFFFF...FFFFED, however big your address register is. Add 0x22+0xFFFFFF...FFFED and you get 0x0F the destination address. You can also take 0xED, invert and add 1 to negate it. ~0xED = 0x12, 0x12+1 = 0x13. So 0xED means subtract 0x13. 0x22-0x13=0x0F.

Here are some more, in each case it gives you the target address which you can just look for in the objdump output.

To understand how it computes that value. Same story, start with opcode at 0x400A81, it takes 6 bytes in this case for the variable length instruction. So by the time you are ready to execute the pc is at 0x400A81+6 = 0x400A87. The offset is 0x107 so if the condition is met the destination address is 0x400A87 + 0x107 = 0x400B8E.

Note these are grepped from a larger program, not sequential code, just a collection of isolated examples.

  400a81:   0f 8f 07 01 00 00       jg     400b8e 
  400a8f:   0f 8f e6 00 00 00       jg     400b7b 
  400a9d:   0f 8f c5 00 00 00       jg     400b68 
  400aab:   0f 8f a4 00 00 00       jg     400b55 
  400ab9:   0f 8f 83 00 00 00       jg     400b42 
  401d76:   0f 8f 31 01 00 00       jg     401ead 
like image 74
old_timer Avatar answered Sep 28 '22 08:09

old_timer