I'm trying to develop my first MIPS stack based exploit, using ROP chain technique with zero luck...I'm failing on the first ROP gadget and I can't figure out why. I'm following Bowcaster python framework and some blog posts I've googled. As the overflow I've found allowing me to overwrite too few S registers (S0 and S8 only) I need to jump to a function epilogue which will set S0-S8 from the stack. I was using IDA PRO with mipsrop plugin to locate the gadgets. I've tried gadgets from both vulnerable binary and libc, but with the same result. I'm seeing in GDB that the $RA register is set correctly to the address I've choose with mipsrop, but for some reason S0-S8 registers are not overwritten. The ASLR is not an issue here as I can confirm that by running ldd few times. I've choose a gadget with the address 000112EC, using IDA PRO, which looks like that : (I can't post more images - reputation)
LOAD:000112EC lw $ra, 0x48+var_4($sp)
LOAD:000112F0 lw $fp, 0x48+var_8($sp)
LOAD:000112F4 lw $s7, 0x48+var_C($sp)
LOAD:000112F8 lw $s6, 0x48+var_10($sp)
LOAD:000112FC lw $s5, 0x48+var_14($sp)
LOAD:00011300 lw $s4, 0x48+var_18($sp)
LOAD:00011304 lw $s3, 0x48+var_1C($sp)
LOAD:00011308 lw $s2, 0x48+var_20($sp)
LOAD:0001130C lw $s1, 0x48+var_24($sp)
LOAD:00011310 lw $s0, 0x48+var_28($sp)
LOAD:00011314 jr $ra
LOAD:00011318 addiu $sp, 0x48
LOAD:00011318 # End of function scandir
I've added the base libc address to it (echo 'obase=16;ibase=16;2AABE000+112EC' | bc) and I've get 0x2AACF2EC. As it's Big Endian processor I've send the string like this :
AAAA and the first gadget address
Below you can see the full output from GDB :
GDB output after the hit
As you can see only S0 and S8 was overwritten and none of S registers was restored from the stack.
What I'm doing wrong here? Please help :)
some checksec.sh output :
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
No RELRO No canary found NX enabled No PIE No RPATH No RUNPATH /bin/vulnbin
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Full RELRO No canary found NX enabled DSO No RPATH No RUNPATH /lib/libc.so.0
You have gdb output after the instructions run but not before (or during)
You should be single stepping and manually checking each load with x/wx $sp+
Could be your string was corrupted and those values in s0-s7 were in fact pulled from the stack as you asked it to do, where your buffer used to be but is now corrupted.
Also, do you have additional bytes in your overflow string after the new $ra value or does that terminate the string? If it's terminating the string then the s0-s7 registers will be filled with garbage stack data.
bottom line: breakpoint the first load, manually x/wx $sp+X each load before it occurs and stepi and confirm the result
If you need a static gdbserver I have a ton for various ARM, MIPS and MIPSEL architectures/ABIs # embedded-toolkit
Related
I'm trying to symbolicate an iOS crash report for which I do not have the dsym file. I know I will not be able to get a nice file_name : line number symbolication but finding out where in the assembly section of the code the crash is will be good enough.
To start with, here is the stack trace of the crashed thread:
Thread 3 name: Dispatch queue: com.unity3d.WebOperationQueue :: NSOperation 0x1483250e0 (QOS: USER_INTERACTIVE)
Thread 3 Crashed:
0 myapp 0x0000000100ec4738 0x100080000 + 14960440
1 myapp 0x000000010120e0fc 0x100080000 + 18407676
2 myapp 0x00000001011d7e00 0x100080000 + 18185728
3 myapp 0x0000000100085cfc 0x100080000 + 23804
4 CFNetwork 0x0000000185027780 __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke + 80
...
I have a decrypted binary and verified the uuid's from crash report and the binary matches. To manually symbolicate a stack address, I do this
atos -arch arm64 -o myapp -l 0x100080000 0x0000000100ec4738
and I get the output from the above command as
0x0000000100e44738 (in myapp) + 544
This is partially expected because I do not have the dsym file.
Please note that 0x0000000100e44738 can also be obtained if we calculate
symbol address as = (slide + stack - load address)
slide is 0x0000000100000000 ( found as vmaddr from otool -arch arm64 -l myapp | grep -B 3 -A 8 -m 2 "__TEXT" )
so 0x0000000100000000 + 0x0000000100ec4738 - 0x100080000 = 0x100e44738 same as above address that atos returned.
Now the problem is, I do not find 0x100e44738 symbol address in the addresses from the TEXT section in the binary that I obtain using below otool command
otool -tvV myapp
The start of the above command looks like this.
myapp:
(__TEXT,__text) section
__ZNK5physx14NpSceneQueries10multiQueryINS_12PxRaycastHitEEEbRKNS_15MultiQueryInputERNS_13PxHitCallbackIT_EENS_7PxFlagsINS_9PxHitFlag4EnumEtEEPKNS_12PxQueryCacheERKNS_17PxQueryFilterDataEPNS_21PxQueryFilterCallbackEPNS_20BatchQueryFilterDataE:
0000000101262f40 stp x28, x27, [sp, #-96]!
0000000101262f44 stp x26, x25, [sp, #16]
0000000101262f48 stp x24, x23, [sp, #32]
0000000101262f4c stp x22, x21, [sp, #48]
0000000101262f50 stp x20, x19, [sp, #64]
0000000101262f54 stp x29, x30, [sp, #80]
...
We can clearly see the starting address from the otool -tvV (0x101262f40) is greater than the symbol address (0x100e44738). So I'm unable to find what I missed or how to go about from here.
This stack trace is for a SIGSEGV exception and I'm not sure if that changes anything. I have tried the exact same steps of manual symbolication in one another sample app with SIGABRT exception and I do see it was able to point out the crash to exact line in the assembly.
Any help or pointers is most appreciated.
I looks like a problem with a NSURLConnection. Usually that means that there is a delegate that is not being unset correctly on dealloc (NSURLConnection is assign - not weak so you have to set it to nil manually). Look for places in your code that use NSURLConnection or other networking like code. Be especially mindful of views or viewController that set themselves as the delegate of network request because views often leave memory when the user leave the page.
I'm currently learning assembly with MSP430.
This simple code should trigger an interrupt for TimerA.
#include "msp430.h" ; #define controlled include file
RSEG CSTACK
RSEG CODE
Reset:
mov.w #WDTPW|WDTHOLD, &WDTCTL ; stop watchdog
mov.w #MC_0|TACLR, &TACTL; stop timer
mov.w #7D0h, &TACCR0; count to 2000
mov.w #CCIE ,&TACCTL0
mov.w #MC_1|TAIE|TASSEL_2, &TACTL; RESET timerA, start it and set clock to VCO
mov.b #BIT0, &P2DIR; output
mov.b #BIT0, &P2OUT;
Main:
mov.w #GIE, SR;
jmp Main;
INTER:
xor.b #BIT0, &P1OUT ; toggle LED
reti
RSEG RESET
DW Reset;
ORG 0xFFF2; address of interrupt
DW INTER
END
But get following error after trying to load code on my MSP:
Error[e104]: Failed to fit all segments into specified ranges. Problem
discovered in segment CODE. Unable to place 1 block(s) (0xfff4 byte(s) total)
in 0x7e0 byte(s) of memory.
The problem occurred while processing the segment placement command
"-P(CODE)CODE=F800-FFDF", where at the moment of placement the
available memory ranges were "CODE:f800-ffdf"
Error while running Linker
I am sure it is some noob error, but can you explain what it is?
Hello and good day to you.
Need a bit of assitance here:
Situation:
I have an obscure DirectX 9 application (name and application details are irrelevant to the question) that causes blue screen of death on all nvidia cards (GeForce 8400GS and up) since certain driver version. I believe that the problem is indirectly caused by DirectX 9 call or a flag that triggers driver bug.
Goal:
I'd like to track down offending flag/function call (for fun, this isn't my job/homework) and bypass error condition by writing proxy dll. I already have a finished proxy dll that provides wrappers for IDirect3D9, IDirect3DDevice9, IDirect3DVertexBuffer9 and IDirect3DIndexBuffer9 and provides basic logging/tracing of Direct3D calls. However, I can't pinpoint function which causes crash.
Problems:
No source code or technical support is available. There will be no assitance, and nobody else will fix the problem.
Memory dump produced by kernel wasn't helpful - apparently an access violation happens within nv4_disp.dll, but I can't use stacktrace to go to IDirect3DDevice9 method call, plus there's a chance that bug happens asynchronously.
(Main problem) Because of large number of Direct3D9Device method calls, I can't reliably log them into file or over network:
Logging into file causes significant slowdown even without flushing, and because of that all last contents of the log are lost when system BSODs.
Logging over network (using UDP and WINSOck's sendto)also causes significant slowdown and must not be done asynchronously (asynchronous packets are lost on BSOD), plus packets (the ones around the crash) are sometimes lost even when sent synchronously.
When application is "slowed" down by logging routines, BSOD is less likely to happen, which makes tracking it down harder.
Question:
I normally don't write drivers, and don't do this level of debugging, so I have impression that I'm missing something important there's a more trivial way to track down the problem than writing IDirect3DDevice9 proxy dll with custom logging mechanism. What is it? What is the standard way of diagnosing/handling/fixing problem like this (no source code, COM interface method triggers BSOD)?
Minidump analysis(WinDBG):
Loading User Symbols
Loading unloaded module list
...........
Unable to load image nv4_disp.dll, Win32 error 0n2
*** WARNING: Unable to verify timestamp for nv4_disp.dll
*** ERROR: Module load completed but symbols could not be loaded for nv4_disp.dll
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck 1000008E, {c0000005, bd0a2fd0, b0562b40, 0}
Probably caused by : nv4_disp.dll ( nv4_disp+90fd0 )
Followup: MachineOwner
---------
0: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Some common problems are exception code 0x80000003. This means a hard
coded breakpoint or assertion was hit, but this system was booted
/NODEBUG. This is not supposed to happen as developers should never have
hardcoded breakpoints in retail code, but ...
If this happens, make sure a debugger gets connected, and the
system is booted /DEBUG. This will let us see why this breakpoint is
happening.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: bd0a2fd0, The address that the exception occurred at
Arg3: b0562b40, Trap Frame
Arg4: 00000000
Debugging Details:
------------------
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".
FAULTING_IP:
nv4_disp+90fd0
bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi
TRAP_FRAME: b0562b40 -- (.trap 0xffffffffb0562b40)
ErrCode = 00000000
eax=00000808 ebx=e37f8200 ecx=e4ae1c68 edx=e37f8328 esi=e37f8400 edi=00000000
eip=bd0a2fd0 esp=b0562bb4 ebp=e37e09c0 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
nv4_disp+0x90fd0:
bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi ds:0023:00000900=????????
Resetting default scope
CUSTOMER_CRASH_COUNT: 3
DEFAULT_BUCKET_ID: DRIVER_FAULT
BUGCHECK_STR: 0x8E
LAST_CONTROL_TRANSFER: from bd0a2e33 to bd0a2fd0
STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
b0562bc4 bd0a2e33 e37f8200 e37f8200 e4ae1c68 nv4_disp+0x90fd0
b0562c3c bf8edd6b b0562cfc e2601714 e4ae1c58 nv4_disp+0x90e33
b0562c74 bd009530 b0562cfc bf8ede06 e2601714 win32k!WatchdogDdDestroySurface+0x38
b0562d30 bd00b3a4 e2601008 e4ae1c58 b0562d50 dxg!vDdDisableSurfaceObject+0x294
b0562d54 8054161c e2601008 00000001 0012c518 dxg!DxDdDestroySurface+0x42
b0562d54 7c90e4f4 e2601008 00000001 0012c518 nt!KiFastCallEntry+0xfc
0012c518 00000000 00000000 00000000 00000000 0x7c90e4f4
STACK_COMMAND: kb
FOLLOWUP_IP:
nv4_disp+90fd0
bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: nv4_disp+90fd0
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: nv4_disp
IMAGE_NAME: nv4_disp.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 4e390d56
FAILURE_BUCKET_ID: 0x8E_nv4_disp+90fd0
BUCKET_ID: 0x8E_nv4_disp+90fd0
Followup: MachineOwner
nv4_disp+90fd0
bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi
This is the important part. Looking at this, it is most probable that eax is invalid, hence attempting to access an invalid memory address.
What you need to do is load nv4_disp.dll into IDA (you can get a free version), check the image base that IDA loads nv4_disp at and hit 'g' to goto address, try adding 90fd0 to the image base IDA is using, and it should take you directly to the offending instruction (depending on section structure).
From here you can analyze the control flow, and how eax is set and used. If you have a good kernel level debugger you can set a breakpoint on this address and try and get it to hit.
Analysing the function, you should attempt to figure out what the function does, what eax is meant to be pointing to at that point, what its actually pointing to, and why. This is the hard part and is a great part of the difficulty and skill of reverse engineering.
Found a solution.
Problem:
Logging is unreliable since messages (when dumped to file) disappear during bsod, packets are sometimes lost when logging over network, and there's slowdown due to logging.
Solution:
Instead of logging to file or over network, configure system to produce full physical memory dump on BSOD and log all messages into any memory buffer. It'll be faster. Once system crashed, it'll dump entire memory into file, and it'll be possible to either view contents of log-file buffer using WinDBG's dt (if you have debug symbols) command, or you'll be able to search and locate logfile stored in memory using "memory" view.
I used circular buffer of std::strings to store messages and separate array of const char* to make things easier to read in WinDBG, but you could simply create huge array of char and store all messages within it in plaintext.
Details:
Entire process on winxp:
Ensure that minimum page file size is equal or larger than total amount of RAM + 1 megabytes. (Right Click "My Computer"->Properties->Advanced->Performance->Advanced->Change)
Configure system to produce complete memory dump on BSOD (RIght click "My Computer'->Properties->Advanced->Startup and Recovery->Settings->Write Debugging Information . Select "Complete memory dump" and specify path you want).
Ensure that disk (where the file will be written) has required amount of free space (total amount of RAM on your system.
Build app/dll (the one that does logging) with debug symbol, and Trigger BSOD.
Wait till memory dump is finished, reboot. Feel free to swear at driver developer while system writes memory dump and reboots.
Copy MEMORY.DMP system produced to a safe place, so you won't lose everything if system crashes again.
Launch windbg.
Open Memory Dump (File->Open Crash Dump).
If you want to see what happened, use !analyze -v command.
Access memory buffer that stores logged messages using one of those methods:
To see contents of global variable, use dt module!variable where "module" is name of your library (without *.dll), and "variable" is name of variable. You can use wildcards. You can use address without module!variable
To see contents of one field of the global variable (if global variable is a struct), use dt module!variable field where "field" is variable member.
To see more details about varaible (content of arrays and substructures) use dt -b module!variable field or dt -b module!variable
If you don't have symbols, you'll need to search for your "logfile" using memory window.
At this point you'll be able to see contents of log that were stored in memory, plus you'll have snapshot of the entire system at the moment when it crashed.
Also...
To see info about process that crashed the system, use !process.
To see loaded modules use lm
For info about thread there's !thread id where id is hexadecimal id you saw in !process output.
It looks like the crash may either be caused by a bad pointer, or heap corruption. You can tell this because the crash occurs in a memory-freeing function (DxDdDestroySurface). Destroying surfaces is something that you absolutely need to do - you can't just stub this out, the surface will still get freed when the program exits, and if you disable it inside the kernel, you'll run out of on-card memory very quickly and crash that way, as well.
You can try to figure out what sequence of events leads up to this heap corruption, but there's no silver bullet here - as fileoffset suggested, you'll need to actually reverse engineer the driver to see why this happens (it may help to compare drivers before and after the offending driver version as well!)
How do I print the value of %eax and %ebp?
(gdb) p $eax
$1 = void
info registers shows all the registers; info registers eax shows just the register eax. The command can be abbreviated as i r
If you're trying to print a specific register in GDB, you have to omit the % sign. For example,
info registers eip
If your executable is 64 bit, the registers start with r. Starting them with e is not valid.
info registers rip
Those can be abbreviated to:
i r rip
There is also:
info all-registers
Then you can get the register name you are interested in -- very useful for finding platform-specific registers (like NEON Q... on ARM).
If only want check it once, info registers show registers.
If only want watch one register, for example, display $esp continue display esp registers in gdb command line.
If want watch all registers, layout regs continue show registers, with TUI mode.
Gdb commands:
i r <register_name>: print a single register, e.g i r rax, i r eax
i r <register_name_1> <register_name_2> ...: print multiple registers, e.g i r rdi rsi,
i r: print all register except floating point & vector register (xmm, ymm, zmm).
i r a: print all register, include floating point & vector register (xmm, ymm, zmm).
i r f: print all FPU floating registers (st0-7 and a few other f*)
Other register groups besides a (all) and f (float) can be found with:
maint print reggroups
as documented at: https://sourceware.org/gdb/current/onlinedocs/gdb/Registers.html#Registers
Tips:
xmm0 ~ xmm15, are 128 bits, almost every modern machine has it, they are released in 1999.
ymm0 ~ ymm15, are 256 bits, new machine usually have it, they are released in 2011.
zmm0 ~ zmm31, are 512 bits, normal pc probably don't have it (as the year 2016), they are released in 2013, and mainly used in servers so far.
Only one serial of xmm / ymm / zmm will be shown, because they are the same registers in different mode. On my machine ymm is shown.
p $eax works as of GDB 7.7.1
Tested as of GDB 7.7.1, the command you've tried works:
set $eax = 0
p $eax
# $1 = 0
set $eax = 1
p $eax
# $2 = 1
This syntax can also be used to select between different union members e.g. for ARM floating point registers that can be either floating point or integers:
p $s0.f
p $s0.u
From the docs:
Any name preceded by ‘$’ can be used for a convenience variable, unless it is one of the predefined machine-specific register names.
and:
You can refer to machine register contents, in expressions, as variables with names starting with ‘$’. The names of registers are different for each machine; use info registers to see the names used on your machine.
But I haven't had much luck with control registers so far: OSDev 2012 http://f.osdev.org/viewtopic.php?f=1&t=25968 || 2005 feature request https://www.sourceware.org/ml/gdb/2005-03/msg00158.html || alt.lang.asm 2013 https://groups.google.com/forum/#!topic/alt.lang.asm/JC7YS3Wu31I
ARM floating point registers
See: https://reverseengineering.stackexchange.com/questions/8992/floating-point-registers-on-arm/20623#20623
Easiest for me is:
(gdb) x/x $eax
First x stands for examine and second x is hex. You can see other formats using:
(gdb) help x
You can easily print strings with x/s $eax or return addresses with x/a $ebp+4.
Is it common for compilers (gcc for instance) to generate an instruction that loads some empty memory element into a register? Like... lw at,0(sp) where memory[sp + 0] = 0. This basically just places 0 into $at ($R1.) I ask because I'm looking through an executable file's hex dump (executable file is the result of the compilation of a c++ file) and I'm manually verifying it and if I start at the objdump state entry point I run into an instruction that does this. I'm not sure whether I should take this to be an error if it's just a common compiler action. It seems like a poor way to zero a register. ADDU $at,$0,$0 would be better. Or SLL $at,$0,$0..
The entry point is 400890. The jump target of the jal at the end is an empty memory location (tells me something is probably wrong...) Note that my previous example was purposefully arbitrated.
And just to be clear, -32636+gp is an empty memory location. I can post the memory contents at the point if you'd like proof :).
00400890 <__start>:
400890: 03e00021 move zero,ra
400894: 04110001 bal 40089c <__start+0xc>
400898: 00000000 nop
40089c: 3c1c0fc0 lui gp,0xfc0
4008a0: 279c7864 addiu gp,gp,30820
4008a4: 039fe021 addu gp,gp,ra
4008a8: 0000f821 move ra,zero
4008ac: 8f848034 lw a0,-32716(gp)
4008b0: 8fa50000 lw a1,0(sp)
4008b4: 27a60004 addiu a2,sp,4
4008b8: 2401fff8 li at,-8
4008bc: 03a1e824 and sp,sp,at
4008c0: 27bdffe0 addiu sp,sp,-32
4008c4: 8f878054 lw a3,-32684(gp)
4008c8: 8f888084 lw t0,-32636(gp)<------ this instruction
4008cc: 00000000 nop
4008d0: afa80010 sw t0,16(sp)
4008d4: afa20014 sw v0,20(sp)
4008d8: afbd0018 sw sp,24(sp)
4008dc: 8f998068 lw t9,-32664(gp)
4008e0: 00000000 nop
4008e4: 0320f809 jalr t9
4008e8: 00000000 nop
Jal target is 4010c0.
4010c0: 8f998010 lw t9,-32752(gp)
4010c4: 03e07821 move t7,ra
4010c8: 0320f809 jalr t9
Perhaps it's being placed after a jump statement? If so, that statement is run before the jump occurs and could be a do nothing instruction (nop). Beyond that, it could just be the compiler on a lower optimization setting. Another possibility is that the compiler is preserving the CPU flags field. Shift and Add play with flags while a load I don't believe does.
This looks like CRT code. I think this code is loading some parameters passed by the OS in to $a0 and $a1 registers. Probably some larger structure is passed on the stack and code is loading that structure in to correct stack location.
This code is probably not generated by C compiler but hand coded in assembly.