porting c function to NASM - c

I want to port this c++ function to NASM.
DWORD WINAPI Generic(LPVOID lpParameter) {
__asm {
mov eax, [lpParameter]
call eax
push 0
call ExitThread
}
return 0;
}
I have some problems understanding how lpParameter works here, and i have and error there when i compile this on NASM.
this is my current code:
BITS 32
global _start
_start:
mov eax, [lpParameter]
call eax
push 0
call exitfunk
exitfunk:
mov ebx, 0x0A2A1DE0
push 0x9DBD95A6
call ebp
cmp al, byte 6
jl short goodbye
cmp bl, 0xE0
jne short goodbye
mov ebx, 0x6F721347
goodbye:
push byte 0
push ebx
call ebp
any one can help me?

IIRC, NASM does not support named function parameters, and so you have to extract the parameters manually from registers or the stack. AFAIR, all Win32 API functions expect parameters on the stack, so you should replace this
mov eax, [lpParameter]
with this
mov eax, [esp+4]

Related

Simple x86 Assembly Loop- Using PTR

I'm learning x86 assembly and loops are very confusing to me.
For the prompt: "Write a program that uses the variables below and MOV instructions to copy the value from bigEndian to littleEndian, reversing the BYTE order.You will need to use PTR or LABLE to access just a BYTE of the
DWORD element, and use LOOP (set ECX to 4) and ESI and EDI for indirect
addressing."
My code displays 76993356
Should I be using PTR with bigEndian instead of just looping like this?
INCLUDE Irvine32.inc
.data
; declare variables here
bigEndian DWORD 12345678h
littleEndian DWORD 0
.code
main proc
mov ECX, SIZEOF bigEndian
mov EDI, OFFSET littleEndian
mov ESI, OFFSET bigEndian
TOP:
mov al, [ESI]
mov [EDI], al
inc ESI
dec EDI
loop TOP
mov edx, littleEndian
call WriteHex
exit
main ENDP
END main

Mixing C and Assembly

I'm doing a program in assembly to read a disk through ports (0x1f0-0x1f7) and I'm mixing it with c. I have a function in assembly that I will call in my c main funtion. My main function as 1 parameter: sectors to read:
Kernel.c
extern int _readd(int nmrsector);
(...)
int sector = 257;
int error = _readd(sector);
if(error == 0) PrintString("Error"); //It is declared on my screen.h file
disk.asm
global _readd
_readd:
push eax
push ebx
push ecx
push edx
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov ecx, eax
cmp ecx, 256
jg short _fail
jne short _good
_fail:
xor eax, eax
leave
ret
_good:
xor eax, eax
mov eax, 12
leave
ret
It crashes when run it with VirtualBox. Any ideas?
If you save CPU registers when you enter a function, you need to restore them when you are finished. Your PUSHs need to be matched with POPs.
Also, if you use a stack frame to access local variables and parameters, setup the frame (push ebp ; mov ebp, esp) before everything, so you can more easily refer to them. Here [ebp+8] doesn't refer to a parameter, because you alter the stack before setting up the frame.

Sleep() inline assembly call works but generates runtime check-failure

As the title of my question says the sleep() function works properly (and every other function call in the C function, the problem is that after it's finished running I get an error that says:
"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
I believe the way I'm handling the registers when I call the sleep function is done properly because it actually works, I posted the whole function just in case it's needed to detect where I might be misplacing the stack contents in another function call.
The function basically prints an elevator going up from the last floor on the bottom to the top-most one.
int deSubidaASM() {
int sleepTime = 900;
char *clear = "cls";
char *piso = "[x]";
char *pisoVacio = "[ ]";
char *texto = "%s\n";
char *fuerza = "Fuerza G: 1";
_asm {
mov ebx, 0 //int a=0
mov ecx, 9 //int b=9
_while1: //while (a <= 9)
cmp ebx, 9 //
jg _fin //if ebx>9, end
_Fuerza: //writes on screen
mov eax, fuerza
push eax
mov eax, texto
push eax
mov esi, ecx //
call printf
mov ecx, esi //
pop edx
pop edx
_sleep:
mov eax, sleepTime
push eax //pushes the sleep time input
mov esi, ebx //auxiliary variable to keep the cycle counters
mov edi, ecx //same as the above line comment
call Sleep //sleep() call
mov ecx, edi //returns the values from the aux variables
mov ebx, esi //same as the above line comment
pop eax //cleans the stack
_clearscreen:
mov eax, clear //Bloque para clearscreen
push eax
mov esi, ebx
mov edi, ecx
call system
mov ecx, edi
mov ebx, esi
pop edx
_while2 : //while (b >= 0)
cmp ecx, 0 //
jle _resetearWhile2 //if ecx<0 restart while2
cmp ebx, ecx // if the levels match
je _printPiso //print elevator
jne _printVacio //print floor
_printPiso :
mov eax, piso
push eax
mov eax, texto
push eax
mov esi, ecx //
call printf
mov ecx, esi //
pop edx
pop edx
dec ecx
jmp _while2
_printVacio :
mov eax, pisoVacio
push eax
mov eax, texto
push eax
mov esi, ecx //
call printf
mov ecx, esi //
pop edx
pop edx
dec ecx
jmp _while2
_resetearWhile2:
mov ecx, 9 //b=9
inc ebx
jmp _while1
_fin :
}
}
The WinApi Sleep() function follows the STDCALL calling convention. It had already cleaned up the stack when it returns. When you do the same, the stack is "overcleaned" ;-). Remove the line:
pop eax //cleans the stack
I don't know what compiler you use. My compiler (Visual Studio 2010) needs another call to Sleep():
call dword ptr [Sleep]
Too much for a comment. I mean push and pop the registers you are interested in preserving, including those you are juggling around from esi <-> ebx and edi <-> ecx.
_sleep:
push ecx // save the regs
push edx
push ebp
mov eax, sleepTime // func argument
push eax // pushes the sleep time input
call Sleep // sleep() call
pop eax // clean off stack
pop ebp // restore regs
pop edx
pop ecx

I am dealing with a possible array in assembly, but I cannot figure out what the starter value is

Size contains the number 86.
var_10= dword ptr -10h
var_C= dword ptr -0Ch
size= dword ptr 8
push ebp
mov ebp, esp
sub esp, 28h
mov eax, [ebp+size]
mov [esp], eax ; size
call _malloc
mov ds:x, eax
mov [ebp+var_C], 0
jmp short loc_804889E
loc_804889E: ~~~~~~~~~~~~~~~~~~~~~
mov eax, [ebp+size]
sub eax, 1
cmp eax, [ebp+var_C]
jg short loc_8048887
loc_8048887: ~~~~~~~~~~~~~~~~~~~~~
mov edx, ds:x
mov eax, [ebp+var_C]
add edx, eax
mov eax, [ebp+var_C]
add eax, 16h
mov [edx], al
add [ebp+var_C], 1
I am having difficulties reversing this portion of a project I am working on. There's a portion of the code where ds:x is moved into edx and is added with var_c and I am unsure where to go with that.
To me the program looks like it calls malloc and then moves that into ds:x and then moves 0 to var_c.
After that it simply subtracts 1 from the size of my pointer array and compares that number to 0, then jumps to a portion where it adds ds:x into edx so it can add eax to edx.
Am I dealing with some sort of array here? What is the first value that's going to go into edx in loc_8048887? Another way this could help would be to see a C equivalent of it... But that would be what I am trying to accomplish and would rather learn the solution through a different means.
Thank you!
In x86 assembly there's no strict distinction between a variable stored in memory and an array in memory. It only depends on how you access the memory region. All you have is code and data. Anyway, I'd say that ds:x is an array as because of this code here:
mov edx, ds:x ; edx = [x]
mov eax, [ebp+var_C] ; eax = something
add edx, eax ; edx = [x] + something
mov eax, [ebp+var_C] ; eax = something
add eax, 16h ; eax = something + 0x16
mov [edx], al ; [[x] + something ] = al . Yes, ds:x is an array!
What is the value of edx in loc_8048887? To find it out you only need some very basic debugging skills. I assume you have gdb at hand, if not, get it ASAP. Then compile the code with debug symbols and link it, then run gdb with the executable, set a code breakpoint at loc_8048887, run the program with r, and finally check the value of edx.
These are the commands you need:
gdb myexecutable
(gdb) b loc_8048887
(gdb) r
(gdb) info registers edx

Get address of current instruction for x86 [duplicate]

This question already has answers here:
Reading program counter directly
(7 answers)
Closed 4 years ago.
I am using Linux with x86 (64 bit to be precise). Is there a way I can get the address of the current instruction. Actually I want to write my own simplified versions of setjmp/longjmp. Here, R.. posted a simplified version of longjmp. Any idea how setjmp is implemented. A simplified version that is, without taking into account of exceptions and signals etc...
I believe in 64-bit code you can simply do lea rax, [rip].
The 32-bit idiom is:
call next
next: pop eax
If using GCC, you could also use __builtin_return_address
The offset-into-the-current-segment register (EIP) is not normally accessible. However, there is a hackish-way to read it indirectly - you trick the program into pushing the value of EIP onto the stack, then just read it off. You could create a subroutine that looks like this:
GetAddress:
mov eax, [esp]
ret
...
call GetAddress ; address of this line stored in eax
Or, even simpler:
call NextLine
NextLine:
pop eax ; address of previous line stored in EAX
If you use a CALL FAR instruction, the segment value (CS) will be pushed on the stack as well.
If you're using C, there are various compiler-specific C-extensions you could use on this page. See also this interesting article.
This site gives a simple version of setjmp and longjmp, which is as follows.
#include "setjmp.h"
#define OFS_EBP 0
#define OFS_EBX 4
#define OFS_EDI 8
#define OFS_ESI 12
#define OFS_ESP 16
#define OFS_EIP 20
__declspec(naked) int setjmp(jmp_buf env)
{
__asm
{
mov edx, 4[esp] // Get jmp_buf pointer
mov eax, [esp] // Save EIP
mov OFS_EIP[edx], eax
mov OFS_EBP[edx], ebp // Save EBP, EBX, EDI, ESI, and ESP
mov OFS_EBX[edx], ebx
mov OFS_EDI[edx], edi
mov OFS_ESI[edx], esi
mov OFS_ESP[edx], esp
xor eax, eax // Return 0
ret
}
}
__declspec(naked) void longjmp(jmp_buf env, int value)
{
__asm
{
mov edx, 4[esp] // Get jmp_buf pointer
mov eax, 8[esp] // Get return value (eax)
mov esp, OFS_ESP[edx] // Switch to new stack position
mov ebx, OFS_EIP[edx] // Get new EIP value and set as return address
mov [esp], ebx
mov ebp, OFS_EBP[edx] // Restore EBP, EBX, EDI, and ESI
mov ebx, OFS_EBX[edx]
mov edi, OFS_EDI[edx]
mov esi, OFS_ESI[edx]
ret
}
}

Resources