Assembly showing a lot of repeating code? - c++

So I'm working on some binary to assembly to c++ code. It's for a project.
When I disassemble the binary I'm getting a lot of repeating assembly code and I'm not sure what it's doing. It's almost like it's just pointing it's way down.
0x0000000000000000 <+0>: push %rbp
0x0000000000000001 <+1>: mov %rsp,%rbp
0x0000000000000004 <+4>: lea 0x0(%rip),%rsi # 0xb <main+11>
0x000000000000000b <+11>: lea 0x0(%rip),%rdi # 0x12 <main+18>
0x0000000000000012 <+18>: callq 0x17 <main+23>
0x0000000000000017 <+23>: callq 0x1c <main+28>
0x000000000000001c <+28>: mov %eax,0x0(%rip) # 0x22 <main+34>
0x0000000000000022 <+34>: mov 0x0(%rip),%eax # 0x28 <main+40>
0x0000000000000028 <+40>: cmp $0x1,%eax
0x000000000000002b <+43>: je 0x40 <main+64>
0x000000000000002d <+45>: lea 0x0(%rip),%rsi # 0x34 <main+52>
0x0000000000000034 <+52>: lea 0x0(%rip),%rdi # 0x3b <main+59>
0x000000000000003b <+59>: callq 0x40 <main+64>
0x0000000000000040 <+64>: mov 0x0(%rip),%eax # 0x46 <main+70>
0x0000000000000046 <+70>: cmp $0x1,%eax
So the repeating code is the "lea" and "callq". Based on the way I'm reading it, it's just pointing to the next line down. For example, the first lea ends with #0xb <main+11> which is the line right below it, and that one points to the line below it, and so on. Can anyone help with what I'm looking at?
There's at least a hundred extra lines in the project, so I'm not looking for a free A, I just need help understanding.
Edit: I am working with a .o file without access to the original .cpp file and the task is to use GDB and Bless to help me read the Assembly output and reassemble it into a .cpp file that works the same as the original code.

So the repeating code is the "lea" and "callq".
The addresses suggest that you are disassembling .o file, not an executable (you should always show the command you used when asking about its output).
Try objdump -dr foo.o instead -- the picture should become much clearer.
P.S. GDB isn't really the right tool for looking at .o files anyway.
Update:
I tried the objdump -dr Project1.o and got pretty much the same output
Look closer: it's not the same output. objdump will display relocations, which show where he CALL will actually go to.
You should also be able to link Project1.o into an executable (something like gcc Project1.o -o Project1), and run gdb Project1 and then disas main. You will see that that disassembly makes more sense, and also matches the output of objdump.

Related

How can i debug the CodeStubAssembler(CSA) code in v8 line by line

I have seen the good answer to my quesntion from Debugging CodeStubAssembler (CSA) code in V8. howerver,i really cannot understand the point "You can then step through the CSA code as it emits a Turbofan IR graph which the Turbofan backend will then translate to machine code" in upshot one.Can I debug CSA line by line according to the source code in that way?
In order to express my needs more clearly,I use some code examples:
2864 TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
2865 TNode<JSArray> array,
2866 CodeStubArguments* args,
2867 TVariable<IntPtrT>* arg_index,
2868 Label* bailout) {
2869 Comment("BuildAppendJSArray: ", ElementsKindToString(kind));
2870 Label pre_bailout(this);
2871 Label success(this);
2872 TVARIABLE(Smi, var_tagged_length);
The above is the code in CSA,Can I enter 'n' in gdb and then single step from line 2869 to line 2870 ?
Just to be clear,Can I get the following format for debugging CSA code?
[───────────────────────────────────────────────────────────────────────────────────────DISASM───────────────────────────────────────────────────────────────────────────────────────]
0x7f9fc9bcaca5 mov rax, qword ptr [rbp - 0x60]
0x7f9fc9bcaca9 mov rcx, qword ptr fs:[0x28]
0x7f9fc9bcacb2 mov rdx, qword ptr [rbp - 8]
0x7f9fc9bcacb6 cmp rcx, rdx
0x7f9fc9bcacb9 mov qword ptr [rbp - 0xb0], rax
► 0x7f9fc9bcacc0 jne 0x7f9fc9bcacd6
0x7f9fc9bcacc6 mov rax, qword ptr [rbp - 0xb0]
0x7f9fc9bcaccd add rsp, 0xb0
0x7f9fc9bcacd4 pop rbp
0x7f9fc9bcacd5 ret
0x7f9fc9bcacd6 call __stack_chk_fail#plt <0x7f9fcb191dc0>
[───────────────────────────────────────────────────────────────────────────────────────SOURCE───────────────────────────────────────────────────────────────────────────────────────]
457 // static
458 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
459 Handle<Object> receiver, int argc,
460 Handle<Object> argv[]) {
461 return Invoke(isolate, InvokeParams::SetUpForCall(isolate, callable, receiver,
462 argc, argv));
463 }
464
465 MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
466 Handle<JSFunction> builtin,
[───────────────────────────────────────────────────────────────────────────────────────STACK
Yes, you can do that, just like for any other C++ code.
Of course, this code runs as part of mksnapshot, and what it does is it creates (part of) a "builtin" code object that can handle appending elements to JavaScript arrays. Line 2869 will put a comment into the code object's comment section (if you are running with the --code-comments flag), line 2870 will define a label that will be used for conditional jumps later.
So just to be clear, this code does not run when you actually append elements to arrays. At that time, the builtin generated by this code will run, and debugging that requires different techniques (see the other answer).
EDIT to address questions in comments:
If i enter p kind in line 2870,can i get the value of kind? if i enter p ElementsKindToString in this function,can i get the address of function ElementsKindToString?
Yes, of course, this is plain C++. (Also, why do you ask? Just try it!)
how could i break in gdb before the Turbofan backend translate this function to machine code and get the debugging format i posted above.
Run mksnapshot in GDB and set a breakpoint on the line you want, then switch the view mode as desired. (Again, this is regular GDB usage; if you need a GDB tutorial then please search for one, there are plenty on the 'net.)
While you haven't directly asked for it, I have a suspicion that what you really want to do is step through the generated builtins instruction-by-instruction and see the CSA source that was responsible for generating them. That, unfortunately, is not possible, because the builtins and their generators run at different times (and even in different binaries!).

How to trick the ja, xor and jle instruction in gdb by setting flags?

I can "trick" the debugger into thinking that a cmp is setting the flag 0 by setting the ZF myself, and if there is a je after the comparaison, it will jump where I want.
Now my question is how do I set flag so that after a compare like:
cmp rcx,0xfcf the ja will succeed and jump where I want?
I have the same question for the following sequence:
xor rcx,QWORD PTR fs:0x28
je 0x5629580fc209 <function+538>
How can I set flag for the je to be successful? Do I have to just set ZF?
Finally, what about
jle? What kind of flag have to be set?
How can I set flag for the je to be successful? Do I have to just set ZF?
Yes.
what about JLE ?
Likewise.
P.S. You could also use GDB jump *0x5629580fc209 command without changing the flags at all.

What are those numbers in gdb?

I disassemble my C code (just printf("hello world") ) in gdb and I got
0x0000000000001135 <+0>: push rbp
0x0000000000001136 <+1>: mov rbp,rsp
0x0000000000001139 <+4>: lea rdi [rip+0xec4] # 0x2004
0x0000000000001140 <+11>: mov eax,0x0
0x0000000000001145 <+16>: call 0x1030 <printf#plt>
0x000000000000114a <+21>: mov eax,0x0
0x000000000000114f <+26>: pop rbp
0x0000000000001150 <+27>: ret
I set break point to main and exam rip register.
rip 0x555555555139 0x555555555139 <main+4>
What are those numbers in font of < > in gdb?
I can only access the memory that rip point to.
if those numbers aren't memories can I change format that make gdb display memory?
Sorry for my bad English.
What are those numbers in font of < > in gdb? I can only access the memory that rip point to.
You are dealing with a position independent executable, which is linked to load at address 0, but is relocated at runtime to a different address (in your case, 0x555555554000).
You likely performed disas before running the application (i.e. before the relocation happened). If instead you do this:
(gdb) start
(gdb) disas main
then GDB will show you relocated instructions.

segmentation fault has occurred on a code which was not compiled using debugger flags

one of process on my system has got segmentation fault .
From core files , I got the below information .
#0 0x00007f8768c06cfb in TestDummy::work() () from libCont.so
#1 0x00007f8768bfb5ee in Test::work() () from libCont.so
#2 0x00007f8768c5fa7b in Test::worker_threads() () from libCont.so
#3 0x00007f873fffe830 in ?? ()
#4 0x0000000000000000 in ?? ()
Please note I am unable to re create this segmentation fault , all i have is this core file on a system to identify what went wrong .
Note: code was not compiled using debugger flag i.e "g++ -g" , so debug information is not available .
What I tried
I tried to dissemble and read complete frame 0 to identify the exact crash point but it didn't help .
can anybody let me know a way to debug it further?
What I tried I tried to dissemble and read complete frame 0 to identify the exact crash point but it didn't help
You don't need to identify the exact crash point: GDB has already told you what it is: it's the instruction at address 0x7f8768c06cfb.
What you are probably saying is "despite looking at disassembly, I still can't understand which source line caused the problem". We could help you with that, but only if you actually show the source and the disassembly in your question.
Your only other choices are:
Find a local guru who you can show the source and the disassembly, and who will help you the same way we would, or
Do what Lightness Races in Orbit told you to do: rebuild your binary with exactly the same flags, but add -g as well. Assuming you have a hermetic build and can rebuild your original binary in a close enough state (output from nm new-binary should match output from nm old-binary), GDB will then tell you exactly what line the address 0x7f8768c06cfb corresponds to.
Note: you don't actually have to rebuild the entire binary with -g. Rebuilding just the source containing TestDummy::work() and re-linking libCont.so should be enough.
I think there a way by which we can debug the core which is not compiled using debugger flags . I would like to explain it with below example .
(gdb) disassemble
Dump of assembler code for function mystrcpy:
0x0804852a <+0>: push %ebp
0x0804852b <+1>: mov %esp,%ebp
0x0804852d <+3>: sub $0x10,%esp
0x08048530 <+6>: mov 0x8(%ebp),%eax
0x08048533 <+9>: mov %eax,-0x4(%ebp)
0x08048536 <+12>: jmp 0x8048540 <mystrcpy+22>
0x08048538 <+14>: addl $0x1,0xc(%ebp)
0x0804853c <+18>: addl $0x1,0x8(%ebp)
0x08048540 <+22>: mov 0xc(%ebp),%eax
0x08048543 <+25>: movzbl (%eax),%edx
0x08048546 <+28>: mov 0x8(%ebp),%eax
=> 0x08048549 <+31>: mov %dl,(%eax)
0x0804854b <+33>: mov 0x8(%ebp),%eax
0x0804854e <+36>: movzbl (%eax),%eax
0x08048551 <+39>: test %al,%al
0x08048553 <+41>: jne
0x8048538 <mystrcpy+14>
0x08048555 <+43>: mov -0x4(%ebp),%eax
0x08048558 <+46>: leave
0x08048559 <+47>:
ret End of assembler dump.
Now , line which is actually showing "=>" symbol is the culprit .(=> 0x08048549 <+31>: mov %dl,(%eax) )
We can use gdb commands to figure out what had happened with line which is showing the problem .
gdb) print $eax //print command
$1 = 0
(gdb) print $dl
$2 = 118
(gdb) print/c $dl
$3 = 118 'v‘
(gdb) info frame //info frame command
Stack level 0, frame at 0xffbf8b90: eip = 0x8048549 in mystrcpy; saved eip = 0x80485cd called by frame at 0xffbf8bc0 Arglist at 0xffbf8b88, args: Locals at 0xffbf8b88, Previous frame's sp is 0xffbf8b90 Saved registers: ebp at 0xffbf8b88, eip at 0xffbf8b8c
(gdb) x/x $ebp+4 //base pointer + 4
0xffbf8b8c: 0x080485cd
(gdb) info symbol 0x080485cd //info symbol command
connect + 115 in section .text of /home/vmahajan/a.out
(gdb) x/x $ebp+4
0xffbf8b8c: 0x080485cd
(gdb) x/x $ebp+8
0xffbf8b90: 0x00000000
(gdb) x/x $ebp+12
0xffbf8b94: 0xffbf91f3
(gdb) print/s (char *)0xffbf91f3
$5 = 0xffbf91f3 "vishal“

Where is Dhcpv6CApiInitialize?

I was trying to do a dynamic loading of dhcpcsvc6.dll to support ipv6 on win7 and ipv4 on xp. But GetProcAddress of Dhcpv6CApiInitialize always fails. So I used exescope to examine the exports of the dll, this is what I got.
Version: 6.1.7600.16385.
00000001 404632EA Dhcpv6AcquireParameters
00000002 40463E4F Dhcpv6CancelOperation
00000003 40463EB9 Dhcpv6EnableTracing
00000004 40461D3B Dhcpv6FreeLeaseInfo
00000005 404644D3 Dhcpv6GetTraceArray
00000006 404645D9 Dhcpv6GetUserClasses
00000007 404642D1 Dhcpv6IsEnabled
00000008 40461730 Dhcpv6QueryLeaseInfo
00000009 40463419 Dhcpv6ReleaseParameters
0000000A 40463E31 Dhcpv6ReleasePrefix
0000000B 40463BF5 Dhcpv6ReleasePrefixEx
0000000C 40463BD1 Dhcpv6RenewPrefix
0000000D 40463892 Dhcpv6RenewPrefixEx
0000000E 40463F51 Dhcpv6RequestParams
0000000F 40463871 Dhcpv6RequestPrefix
00000010 40463549 Dhcpv6RequestPrefixEx
00000011 404647D1 Dhcpv6SetUserClass
Dhcpv6CApiInitialize is not in it. I also tried dhcpcore6.dll, dhcpsvc.dll and 64bit versions of these.. no findings.
I wonder where this function really is? Do I really have to call it before any other dhcp v6 apis?
MSDN reference: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363306(v=vs.85).aspx
TL;DR
Functions are not present until Win8. The Win8 version (I examined version 6.2.9200.16433) does nothing useful. It seems safe to ignore these functions if they're not present in dhcpcsvc6.DLL.
Explanation:
Statically linking requires Win8 SDK (already built into VS2012).
VS2010 with Win7 SDK won't compile.
When compiled with Win8 SDK, the compiled exe won't run on Win7, saying The procedure entry point Dhcpv6CApiInitialize could not be located in the dynamic link library dhcpcsvc6.DLL. That means that the functions are indeed exported from dhcpcsvc6.DLL.
Win8 version of the DLL does contain these functions.
_Dhcpv6CApiInitialize#4 essentially just puts 2 to output parameter:
10004199: mov edi,edi // Standard Hotpatch spot
1000419B: push ebp // Standard Prologue
1000419C: mov ebp,esp // Standard Prologue
1000419E: mov eax,dword ptr [ebp+8] // eax <- param0
100041A1: test eax,eax // if (param0 == 0)
100041A3: je 100041AB // return;
100041A5: mov dword ptr [eax],2 // *param0 = 2;
100041AB: pop ebp // Standard epilogue
100041AC: ret 4 // end of function
_Dhcpv6CApiCleanup#0 does nothing at all:
100041B6: ret