I am newbie in assembler. I need to change text color in loop (5 time - 5 different colors) using Masm32. My code:
Main PROC
LOCAL hStdout:DWORD
call SetConsoleTitleA
push -11
call GetStdHandle
mov hStdout,EAX
mov BX,5
lp:
push hStdout
push 2
call SetConsoleTextAttribute
push 0
push 0
push 24d
push offset sWriteText
push hStdout
call WriteConsoleA
dec BX
jnz lp
push 2000d
call Sleep
push 0
call ExitProcess
Main ENDP
end Main
P.S. Sorry for my Enlish.
Problem 1
As hinted to by Raymond Chen is that the call to SetConsoleTitle is incorrect.
Main PROC
LOCAL hStdout:DWORD
call SetConsoleTitleA
Notice that you don't push any arguments onto the stack for SetConsoleTitle. This means that after this call the stack is corrupted.
Once this is fixed we can move on to problem 2.
Problem #2
According to the __stdcall calling convention arguments are pushed right-to-left. But in the code the arguments are being pushed left-to-right. In the code above this is the call sequence for SetConsoleTextAttribute
push hStdout
push 2
call SetConsoleTextAttribute
Given the function's signature:
BOOL WINAPI SetConsoleTextAttribute(
_In_ HANDLE hConsoleOutput,
_In_ WORD wAttributes
);
The code is calling this function like the following C code,
SetConsoleTextAttribute(2, hStdout);
which is reversed. The call should be:
push 2
push hStdout
call SetConsoleTextAttribute
Problem 3
The code ignores all return values, except for GetStdHandle. For SetConsoleTextAttribute the return value is nonzero if the function was successful. If the function returns zero, then the function call failed, and for this function1 extended error information is available by calling GetLastError. The documentation on MSDN has information about each of the other functions and how they indicate errors.
1Not all functions call SetLastError when they fail. There are a lot of issues caused by thinking otherwise. Also of note that functions that do set the error, only do so when they have an error.
Also worth a read is The History Of Calling Conventions series over at The Old New Thing.
Related
As I am learning reverse engineering, I'm doing Lena's tutorials on the matter. On the third exercice, I don't understand why the GetModuleHandleA function is called to get a handle of the current file. Just after that, the program checks if it failed and show the bad boy. (Pop-up we want to remove.)
Because ASM code worth a thounsand words, here's more details:
PUSH 0 // Entry point!
CALL <JMP.&KERNEL32.GetModuleHandleA> // Returns 00400000 (RegisterMe.<STRUCT IMAGE_DOS_HEADER>)
MOV DWORD PTR DS:[40311C], EAX
CMP EAX,0
,- JE SHORT RegisterMe.00401024
| [...] // Annoying pop-up
`-> [...] // Rest of the program
According to the MSDN page for GetModuleHandleA, :
If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
I have two questions:
Why does the GetModuleHandleA returns a pointer to IMAGE_DOS_HEADER? I expected it to return a handle to a file.
In which cicumstances would the jump have been taken? (In other words, how could the GetModuleHandleA fail?)
To me, the only scenario that can skip the annoying pop-up is if the function fails. Am I wrong or is this not realistic?
If I am using the Win32 entry point and I have the following code (in NASM):
extern _ExitProcess#4
global _start
section .text
_start:
mov ebp, esp
; Reserve space onto the stack for two 4 bytes variables
sub esp, 4
sub esp, 4
; ExitProcess(0)
push 0
call _ExitProcess#4
Now before exiting the process, should I increase the esp value to remove the two variables from the stack like I do with any "normal" function?
ExitProcess api can be called from any place. in any function and sub-function. and stack pointer of course can be any. you not need set any registers (include stack pointer) to some (and which ?) values. so answer - you not need increase the esp
as noted #HarryJohnston of course stack must be valid and aligned. as and before any api call. ExiProcess is usual api. and can be call as any another api. and like any another api it require only valid stack but not concrete stack pointer value. non-volatile registers need restore only we return to caller. but ExiProcess not return to caller. it at all never return
so rule is very simply - if you return from any function (entry point or absolute any - does not matter) - we need restore non volatile registers (stack pointer esp or rsp based on calling conventions) and return. if we not return to caller - we and not need restore/preserve any registers. if we return from thread or process entry point, despite good practice also restore all registers as well - in current windows implementations - even if we not do this, any way all will be work, because kernel32 shell caller simply just call ExitThread after we return. it not use any non volatile registers or local variables here. so code will be worked even without restore this from entry point, but much better restore it anyway
OK, I'm new to PC Assembler. I"m trying to write an program, but it won't stop looping. I'm guessing the ECX register is being modified? How can I fix this? Thanks.
DATA SECTION
;
KEEP DD 0 ;temporary place to keep things
;
CODE SECTION
;
START:
MOV ECX,12
TOPOFLOOP:
PUSH -11 ;STD_OUTPUT_HANDLE
CALL GetStdHandle ;get, in eax, handle to active screen buffer
PUSH 0,ADDR KEEP ;KEEP receives output from API
PUSH 5,'bruce' ;5=length of string
PUSH EAX ;handle to active screen buffer
CALL WriteFile
XOR EAX,EAX ;return eax=0 as preferred by Windows
LOOP TOPOFLOOP
ENDLABEL:
RET
In most x86 calling convention, including the stdcall convention used by Windows API functions, ECX is a caller-save register -- the called function is not required to make sure the value of the register is the same when it returns as when it was called. You have to save it somewhere safe in your own code.
I need to access the WinMain parameters using assembly, but I don't seem to be able to do so despite that I supposedly know where they are in the stack (DWORD offsets 0 to 16, and 0 to 20 when pushing EBP before operations). Below there's an example for showing the lpszCmdline string which contains the command line of the program, but it always seems to contain 0, so nothing is displayed. If I try to use other arguments in the assembly code, no valid string pointer seems to be present and/or the program crashes, as expected.
;[esp+20]==nCmdShow
;[esp+16]==lpszCmdLine
;[esp+12]==0 in win32
;[esp+8]==hInst
;[esp+4]==EIP
;[esp+0]==EBP
push ebp
mov ebp,esp
mov eax,[ebp+16]
push dword 0x00001030 ;UINT uType
push eax ;LPCTSTR lpCaption
push eax ;LPCTSTR lpText
push dword 0 ;HWND hWnd
call dword[MessageBoxA#USER32.DLL]
pop ebp
However, if I use GetCommandLine I can get a valid pointer to the command line string, and it displays.
call dword[GetCommandLineA#KERNEL32.DLL]
push dword 0x00001030 ;UINT uType
push eax ;LPCTSTR lpCaption
push eax ;LPCTSTR lpText
push dword 0 ;HWND hWnd
call dword[MessageBoxA#USER32.DLL]
Where's the error in the first code block? What do I need to get the parameters, and being able to implement my own code to return a valid pointer to lpszCmdLine just like GetCommandLine and as a result, to the other WinMain parameters? If I can't get the command line pointer from the stack, then I presumably won't be able to get the other parameters, like nCmdShow, for other important initializations.
Please let me know if you need more code than the provided above. If it is useful for you to know, I used no linker but fully manual EXE generation (does it make any difference in WinMain, like further stack parameters?), but basically it's just a program for which Windows automatically calls its entry point and the above would be the 2 different options of what program it would contain.
#include <Windows.h>
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
__asm {
mov eax, [ebp+16]
push 0
push eax
push eax
push 0
call dword ptr ds:[MessageBoxA]
}
return ERROR_SUCCESS;
}
This runs just fine for me within Visual Studio. Oddly running it in a debugger and single stepping causes an access violation when the MessageBox is called. I'm unsure why this is, but running in debug without single stepping as well as running the final binary gives the expected result, ie. a messagebox with caption/message as the argument
I'm trying to call the following function:
long long RtlLargeIntegerDivide(long long dividend, long long divisor, long long* pRemainder)
in assembly code (NASM). It uses the stdcall calling convention, and it returns the quotient. These are the specifications:
Input: [EDX,EAX] (dividend), [ECX,EBX] (divisor)
Output: [EDX,EAX] (quotient), [ECX,EBX] (remainder)
How do I go about doing this? (My main problem is not exactly understanding EBP and ESP, and how they relate to local variables.)
(And no, this isn't homework; I'm trying to implement a wrapper C run-time library.)
Thank you!
In 32 bit mode you don't have to use EBP to access local variables at all, that is just a convention remnant from 16 bit times and doesn't concern us now anyway.
ESP is your stack pointer, I assume you know that. You can "allocate" space for your local variables by decrementing ESP.
stdcall calling convention uses the stack for argument passing. They are in normal order when on the stack, but if you are using PUSH that means you push them reversed. Integral return values are in EAX (and EDX when necessary). The called function cleans up the arguments from the stack.
So the following code should do what you want:
sub ESP, 8; make room for remainder
push ESP ; pass pointer to remainder as argument
push ECX
push EBX ; pass divisor argument
push EDX
push EAX ; pass dividend argument
call RtlLargeIntegerDivide
; quotient returned in EDX:EAX
; so just load remainder from stack
pop EBX
pop ECX
(For speed, you can use MOV instead of PUSH/POP)