So I have the assembly code below and the goal is to run the code without hitting the explode bomb call. The user enters 6 numbers with spaces in between but that part isn't too important as it is mostly handled by the read six numbers function which is known to be good and not explode the bomb.
0x0000000000400f0c <+0>: push %rbp
0x0000000000400f0d <+1>: push %rbx
0x0000000000400f0e <+2>: sub $0x28,%rsp
0x0000000000400f12 <+6>: mov %rsp,%rsi
0x0000000000400f15 <+9>: callq 0x4015da <read_six_numbers>
0x0000000000400f1a <+14>: cmpl $0x0,(%rsp)
0x0000000000400f1e <+18>: jne 0x400f27 <phase_2+27>
0x0000000000400f20 <+20>: cmpl $0x1,0x4(%rsp)
0x0000000000400f25 <+25>: je 0x400f48 <phase_2+60>
0x0000000000400f27 <+27>: callq 0x4015a4 <explode_bomb>
0x0000000000400f2c <+32>: jmp 0x400f48 <phase_2+60>
0x0000000000400f2e <+34>: mov -0x8(%rbx),%eax
0x0000000000400f31 <+37>: add -0x4(%rbx),%eax
0x0000000000400f34 <+40>: cmp %eax,(%rbx)
0x0000000000400f36 <+42>: je 0x400f3d <phase_2+49>
0x0000000000400f38 <+44>: callq 0x4015a4 <explode_bomb>
0x0000000000400f3d <+49>: add $0x4,%rbx
0x0000000000400f41 <+53>: cmp %rbp,%rbx
0x0000000000400f44 <+56>: jne 0x400f2e <phase_2+34>
0x0000000000400f46 <+58>: jmp 0x400f54 <phase_2+72>
0x0000000000400f48 <+60>: lea 0x8(%rsp),%rbx
0x0000000000400f4d <+65>: lea 0x18(%rsp),%rbp
0x0000000000400f52 <+70>: jmp 0x400f2e <phase_2+34>
0x0000000000400f54 <+72>: add $0x28,%rsp
0x0000000000400f58 <+76>: pop %rbx
0x0000000000400f59 <+77>: pop %rbp
0x0000000000400f5a <+78>: retq
I know that the read 6 numbers part works fine and doesnt set off the bomb. All it does is get the input.
Hey I'm not real good at assembly but I'm working on this and I think I've figured out the first number is 0 and the second is 1 but that could be wrong. I see the comparison on line +14 but im not sure if thats comparing the first value or just making sure that the string the user entered wasnt empty. I know you're supposed to put in 6 numbers and that's only the first 2 though. I'm a bit confused about what lines +34 to +40 do. I get that that's where the compared numbers change but I'm not sure how it affects them. If anyone is good with assembly and can help me out that would be awesome.
Related
What do the first three columns stand for after entering the following command
uf nt!KiSwapContext ?
Here is the result displayed in the Windbg command prompt:
lkd> uf nt!KiSwapContext
nt!KiSwapContext:
fffff803`5c143fa0 4881ec38010000 sub rsp,138h
fffff803`5c143fa7 488d842400010000 lea rax,[rsp+100h]
fffff803`5c143faf 0f29742430 movaps xmmword ptr [rsp+30h],xmm6
fffff803`5c143fb4 0f297c2440 movaps xmmword ptr [rsp+40h],xmm7
fffff803`5c143fb9 440f29442450 movaps xmmword ptr [rsp+50h],xmm8
fffff803`5c143fbf 440f294c2460 movaps xmmword ptr [rsp+60h],xmm9
fffff803`5c143fc5 440f29542470 movaps xmmword ptr [rsp+70h],xmm10
.....
Taking for example the following line as shown above what does the first three column addresses stand for ? Could someone also recommend a good place to start learning about the output rendered by Windbg if I wanted to try other Windbg commands ?
fffff803`5c143fa0 4881ec38010000 sub rsp,138h
The first column (fffff803`5c143fa0) is the 64 bit instruction address, the backtick in the middle is only there to make the address easier to read by separating the upper and lower 32 bits of the address. More specifically it's the address of the first byte of the instruction.
The second column (4881ec38010000) is the bytes that make up the instruction, and the remainder of the line (sub rsp,138h) is the instruction decoded into the corresponding assembly (Intel syntax).
I got some inconsistent result of instruction.
I don't know why this happens, so I suspect %es register is doing something weird, but I'm not sure.
Look at below code snippet.
08048400 <main>:
8048400: bf 10 84 04 08 mov $HERE,%edi
8048405: 26 8b 07 mov %es:(%edi),%eax # <----- Result 1
8048408: bf 00 84 04 08 mov $main,%edi
804840d: 26 8b 07 mov %es:(%edi),%eax # <----- Result 2
08048410 <HERE>:
8048410: 11 11 adc %edx,(%ecx)
8048412: 11 11 adc %edx,(%ecx)
Result 1:
%eax : 0x11111111
Seeing this result, I guessed that mov %es:(%edi),%eax to be something like mov (%edi),%eax.
Because 0x11111111 is stored at HERE.
Result 2:
%eax : 0x048410cc
However, the result of Result 2 was quite different.
I assumed %eax to be 0x048410bf, because this value is stored at main.
But the result was different as you can see.
Question:
Why this inconsistency of the result happens?
By the way, value of %es was always 0x7b during execution of both instruction.
es is a red herring. The difference you see is 1 byte at main, cc vs. bf. That is because you used a software breakpoint at main and your debugger inserted an int3 instruction which has machine code cc temporarily overwriting your actual code.
Do not set a breakpoint where you intend to read from, or use a hardware breakpoint instead which does not modify code.
I get the following output when I disassembled a simple ARM binary file using the command "arm-linux-gnueabihf-objdump -d a.out"
00008480 <_start>:
8480: f04f 0b00 mov.w fp, #0
8484: f04f 0e00 mov.w lr, #0
8488: bc02 pop {r1}
848a: 466a mov r2, sp
What do different columns represent here? For example, 8480 and f04f 0b00 (from the 2nd line of code)
The first column is the address of the code in memory. 0x8480 means the memory address of this piece of code is 0x8480.
The second column is the hex representation of the code. f04f 0b00 means from memory address 0x8480(included) to 0x8484(excluded), there are 4 bytes of code, f0, 4f, 0b, 00.
The remaining is the disassembled code. They are disassembled from the code in second column.
I have the following assembly code
.machine power8
.abiversion 2
.section ".toc","aw"
.section .text
GLOBAL(myfunc)
myfunc:
stdu 1,-240(1)
mflr 0
std 0, 0*8(1)
mfcr 8
std 8, 1*8(1)
std 2, 2*8(1)
# Save all non-volatile registers R14-R31
std 14, 4*8(1)
...
# Save all the non-volatile FPRs
...
stwu 1, -48(1)
bl function_call
nop
addi 1, 1, 48
ld 0, 0*8(1)
mtlr 0
ld 8, 1*8(1)
ld 2, 2*8(1)
...
# epilogue, restore stack frame
This works fine with static build but shared build gives segmentation fault in
00000157.plt_call.__tls_get_addr_opt##GLIBC_2.22, should the shared build be handled differently in power8 w.r.t TOC?
The calling convention is the same between POWER 8 and previous processors. However, there has been changes with regards to the TOC pointer (r2) handling between ABIv1 and ABIv2.
In ABIv2, the caller does not establish the TOC pointer in r2; the called function should do this for global entry points (ie, where the TOC pointer may not be the same as that used in the callee). To do this, ABIv2 functions will have a prologue that sets r2:
0000000000000000 <foo>:
0: 00 00 4c 3c addis r2,r12,0
4: 00 00 42 38 addi r2,r2,0
- this depends on r12 containing the address of the function's global entry point (those 0 values will be replaced with actual offsets at final link time).
I don't see any code setting r12 appropriately in your example. Are you sure you're complying with the v2 ABI there?
The ABIv2 spec is available here: https://members.openpowerfoundation.org/document/dl/576 Section 2.3.2 will be the most relevant for this issue.
Right, I'm sure this is implicitly answered many times, but I seem not to be able to quite get to it.
If you have a (x86) stack trace (say, looking at it in WinDbg), and you look at the registers, what does it mean for EBP and ESP values to be x bytes apart?
Links:
https://stackoverflow.com/a/3699916/321013
https://stackoverflow.com/a/2466587/321013
https://stackoverflow.com/a/5738940/321013
To give an example of a recent stack trace I had:
0:016> k
ChildEBP RetAddr
1ac5ee8c 76b831bb ntdll!NtDelayExecution+0x15
1ac5eef4 76b83a8b KERNELBASE!SleepEx+0x65
1ac5ef04 0060e848 KERNELBASE!Sleep+0xf
1ac5ef10 76859d77 MyApp!application_crash::CommonUnhandledExceptionFilter+0x48 [...\applicationcrash.inc.cpp # 47]
1ac5ef98 775a0df7 kernel32!UnhandledExceptionFilter+0x127
1ac5efa0 775a0cd4 ntdll!__RtlUserThreadStart+0x62
1ac5efb4 775a0b71 ntdll!_EH4_CallFilterFunc+0x12
1ac5efdc 77576ac9 ntdll!_except_handler4+0x8e
1ac5f000 77576a9b ntdll!ExecuteHandler2+0x26
1ac5f0b0 7754010f ntdll!ExecuteHandler+0x24
1ac5f0b0 6e8858bb ntdll!KiUserExceptionDispatcher+0xf
1ac5f400 74e68ed7 mfc80u!ATL::CSimpleStringT<wchar_t,1>::GetString [f:\dd\vctools\vc7libs\ship\atlmfc\include\atlsimpstr.h # 548]
1ac5fec0 6e8c818e msvcr80!_NLG_Return [F:\dd\vctools\crt_bld\SELF_X86\crt\prebuild\eh\i386\lowhelpr.asm # 73]
1ac5ff48 74e429bb mfc80u!_AfxThreadEntry+0xf2 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp # 109]
1ac5ff80 74e42a47 msvcr80!_callthreadstartex+0x1b [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c # 348]
1ac5ff88 76833677 msvcr80!_threadstartex+0x66 [f:\dd\vctools\crt_bld\self_x86\crt\src\threadex.c # 326]
1ac5ff94 77569f02 kernel32!BaseThreadInitThunk+0xe
1ac5ffd4 77569ed5 ntdll!__RtlUserThreadStart+0x70
1ac5ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
0:016> r
eax=00000000 ebx=1ac5efc8 ecx=19850614 edx=00000000 esi=1ac5eed0 edi=00000000
eip=7754fd21 esp=1ac5ee8c ebp=1ac5eef4 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
Values of ESP 1ac5ee8c - EBP 1ac5eef4 = 104 bytes difference. So what's in there?
ESP is the current stack pointer. EBP is the base pointer for the current stack frame.
When you call a function, typically space is reserved on the stack for local variables. This space is usually referenced via EBP (all local variables and function parameters are a known constant offset from this register for the duration of the function call.) ESP, on the other hand, will change during the function call as other functions are called, or as temporary stack space is used for partial operation results.
Note that most compilers these days have an option to reference all local variables through ESP. This frees up EBP for use as a general purpose register.
In general, when you look at the disassembly code at the top of a function you'll see something like this:
push EBP
mov EBP, ESP
sub ESP, <some_number>
So EBP will point to the top of your stack for this frame, and ESP will point to the next available byte on the stack. (Stacks usually - but don't have to - grow down in memory.)
Usually, this space is reserved for local variables that end up stored on the stack. At the start of the function, ESP is decremented by the appropriate value.
In your case, there are 104 bytes worth of locals in the function.