I don't know how to ask this better but why does this:
call ExitProcess
do the same as this?:
mov eax, ExitProcess
mov eax, [eax]
call eax
I would think that these would be equivalent:
call ExitProcess
mov eax, ExitProcess
call eax
When importing the code from a DLL, the symbol ExitProcess isn't actually the address of the code that exits your process (it's the address of the address). So, in that case, you have to dereference it to get the actual code address.
That means that you must use:
call [ExitProcess]
to call it.
For example, there's some code at this location containing the following:
;; Note how we use 'AllocConsole' as if it was a variable. 'AllocConsole', to
;; NASM, means the address of the AllocConsole "variable" ; but since the
;; pointer to the AllocConsole() Win32 API function is stored in that
;; variable, we need to call the address from that variable.
;; So it's "call the code at the address: whatever's at the address
;; AllocConsole" .
call [AllocConsole]
However, importing the DLL directly in user code is not the only way to get at the function. I'll explain why you're seeing both ways below.
The "normal" means of calling a DLL function is to mark it extern then import it from the DLL:
extern ExitProcess
import ExitProcess kernel32.dll
:
call [ExitProcess]
Because that sets up the symbol to be an indirect reference to the code, you need to call it indirectly.
After some searching, it appears there is code in the wild that uses the naked form:
call ExitProcess
From what I can tell, this all seems to use the alink linker, which links with the win32.lib library file. It's possible that this library provides the stub for calling the actual DLL code, something like:
import ExitProcessActual kernel32.dll ExitProcess
global ExitProcess
ExitProcess:
jmp [ExitProcessActual]
In nasm, this would import the address of ExitProcess from the DLL and call it ExitProcessActual, keeping in mind that this address is an indirect reference to the code, not the address of the code itself.
It would then export the ExitProcess entry point (the one in this LIB file, not the one in the DLL) so that others could use it.
Then someone could simply write:
extern ExitProcess
:
call ExitProcess
to exit the process - the library would jump to the actual DLL code.
In fact, with a little more research, this is exactly what's happening. From the alink.txt file which comes with the alink download:
A sample import library for Win32 is included as win32.lib. All named exports in Kernel32, User32, GDI32, Shell32, ADVAPI32, version, winmm, lz32, commdlg and commctl are included.
Use:
alink -oPE file[.obj] win32.lib
to include it or specify
INCLUDELIB "win32"
in your source file.
This consists of a series of entries for import redirection - call MessageBoxA, and it jumps to [__imp_MessageBoxA], which is in the import table.
Thus calls to imports will run faster if call [__imp_importName] is used instead of call importName.
See test.asm, my sample program, which calls up a message box both ways:
includelib "win32.lib"
extrn MessageBoxA:near
extrn __imp_MessageBoxA:dword
codeseg
start:
push 0 ; OK button
push offset title1
push offset string1
push 0
call MessageBoxA
push 0 ; OK button
push offset title1
push offset string2
push 0
call large [large __imp_MessageBoxA]
(__imp_MessageBoxA is the symbol imported from the DLL, equivalent to my ExitProcessActual above).
Related
Fairly simple question this time. How do I write to screen the contents of a single register in Assembly? I'm getting a bit tired of calling DumpRegs just to see the value of one register.
I'm using x86 architecture, and MASM in Visual Studio, and Irvine32.lib.
Irvines's DumpReg uses repeatedly a macro of Macros.inc: mShowRegister. It can be used directly. Example:
INCLUDE Irvine32.inc
INCLUDE Macros.inc
.code
main PROC
mov esi, 0DeadBeefh
mShowRegister ESI, ESI
exit
main ENDP
END main
A documented macro with more options is mShow. Example:
INCLUDE Irvine32.inc
INCLUDE Macros.inc
.code
main PROC
mov esi, 0DeadBeefh
mshow ESI, h
exit
main ENDP
END main
Irvine32 has output functions that take a value in EAX, such as WriteDec (unsigned base 10).
See the documentation http://programming.msjc.edu/asm/help/source/irvinelib/writedec.htm which has links to WriteHex (hex = base 16), and WriteInt (signed base 10).
These functions use the Irvine32 calling convention and preserve all registers, including the arg-passing register EAX, so you can even insert them as a debug-print for EAX at least. More usually you'd use them as simply normal output functions.
Usually for asm debugging you'd use a debugger, not debug-print function calls.
I've written a basic program in NASM trying to use FindFileA with a view to eventually listing all files in a directory.
extern FindFirstFileA ; kernel32.dll
extern ExitProcess ; kernel32.dll
section .code
Start:
push dataStructPtr
push searchParameters
call [FindFirstFileA]
mov [fileHandle], eax
push 0
call [ExitProcess]
section .data
searchParameters: db "*.*",0
section .bss
dataStructPtr: resb 4
fileHandle: resb 4
As far as I can tell a 32-bit pointer to the WIN32_FIND_DATAA structure should be going into address 402008.
However it looks like more than 4 bytes are being written and also that gives me an address of 007334C8 which the program memory does not go up to.
Would you be able to shed some light on why this is happening and where the structure resides so I could look at it using OllyDbg?
Using OllyDbg to look at it:
Many Thanks
I am learning assembly using fasm and I am having trouble returning from main after a function call. With an empty program I can get it to work fine
format PE console
entry start
include 'win32a.inc'
section '.text' code executable
start:
push ebp
mov ebp, esp
leave
ret
section '.rdata' data readable
format_str db '%d', 10, 0
section '.idata' data readable import
library msvcrt, 'msvcrt.dll'
import msvcrt, printf, 'printf'
but if I add a function call (printf in this case) like so
format PE console
entry start
include 'win32a.inc'
section '.text' code executable
start:
push ebp
mov ebp, esp
push esp
push format_str ;set to '%d',10,0 in the data section
call [printf]
add esp, 2*4
leave
ret
section '.rdata' data readable
format_str db '%d', 10, 0
section '.idata' data readable import
library msvcrt, 'msvcrt.dll'
import msvcrt, printf, 'printf'
The program will print successfully but will fail to exit the program and crash
What is happening in the function call that causes my return statement to fail and how can I correct for it?
The initial thread in a process basically looks like this:
call LdrLoadAllTheThings ; Might call TLS callbacks etc
call pe_entrypoint ; Your function
push somenumber
call ExitThread ; Exit this thread and possibly the process
A process will end after all threads have exited and just returning will work for very simple programs but as soon as somebody calls CreateThread or one of the thread pool functions the process will no longer end when you just return, it will stick around as long as there are other threads doing work/waiting. On older versions of Windows it was usually OK for console programs to just return but as you have discovered, it only works because the called functions did not create new threads (relying on internal implementation details). In a GUI program it is even less likely to work and hard to debug because things like PlaySound while clicking on a standard UI element might create a thread.
If you build a C/C++ application with the Microsoft toolchain and link with their runtime library then your main function is not the real entry point, the real entry point is mainCRTStartup and it basically works like this:
__declspec(noreturn) void __cdecl mainCRTStartup()
{
int code;
char*argv;
int argc = parse(GetCommandLine(), &argv);
call_constructors();
code = main(argc, argv); // Your main function
call_destructors_and_atexit_callbacks();
ExitProcess(code); // End this thread and all other threads
}
To begin, I'd like to say I have sufficient background in assembly to understand most of what one needs to know to be a functional assembly programmer. Unfortunately I do not understand how a Windows API call works in terms of the return address.
Here's some example code written in GAS assembly for Windows using MinGW's as as the assembler and MinGW's ld as the linker...
.extern _ExitProcess#4
.text
.globl _main
_main:
pushl $0
call _ExitProcess#4
This code compiles and runs after assembling...
as program.s -o program.o
And linking it...
ld program.o -o program.exe -lkernel32
From my understanding, Windows API calls take arguments via push instructions, as can be seen above. Then during the call;
call _ExitProcess#4
the return address for the function is placed on the stack. Then, and this is where I'm confused, the function pops all the arguments off the stack.
I am confused because, since the stack is last in first out, in my mind while popping the arguments on the stack it would pop off the return address first. The arguments came first and the return address came next so it would technically be popped off first.
My question is, what does the layout of the stack look like after passing arguments via push operations to the function call and the return address placed on the stack? How are the arguments and the return address popped off the stack by the function as it executes? And finally, how is the return address popped off the stack and the function call rerturns to the address specified in the return addresss?
Almost all Windows API functions use the stdcall calling convention. This works like the normal "cdecl" convention, except as you've seen the called function is responsible for removing the argument when it returns. It does this using the RET instruction, which takes an optional immediate operand. This operand is the number of bytes to pop off the stack after first popping off the return value.
In both the cdecl and stdcall calling convention the arguments to a function aren't popped off the stack while the function is executing. They're left on the stack and accessed using ESP or EBP relative addressing. So when ExitProcess needs to access its argument it uses an instruction like mov 4(%esp), %eax or mov 4(%ebp), %eax.
I'm attempting to display "Hello, world!" with FASM on a 64-bit Windows 7 machine without using the crutches that modern assemblers seem to provide in abundance.
This rather simple task proved to be surprisingly frustrating since every example and tutorial I could find insists on resorting to macros, including prewritten code, or importing libraries from high-level languages. I thought that the kind of people who want to learn assembly typically do so to develop a direct and intimate understanding of how computers work. All these abstractions and obfuscations seem to detract from that purpose.
Rant aside, I'm looking for code that can display "Hello, world!" on a console without reusing, including, and importing anything except to directly access the Windows API. Although I'm aware that many assemblers come packaged with files that provide access to the Windows API, I'd rather not rely on them.
Also, if you have any suggestions as to what assemblers or tutorials I can use to better facilitate my approach to learning, I'd greatly appreciate it.
The big problem with "pure" windows programming is that Windows require that the program contains import section, about what functions from the system DLLs have to be provided to the program - so called import table.
This table is not a part of the program and has nothing to do with assembly programming itself. Besides, the import table has complex structure, not very convenient to be manually build. That is why FASM provides some standard way for the user to build these import tables.
The proper approach to you, if you goal is to learn assembly, is to read the FASM manuals, where these macros are described, then to read the example code provided in any FASM distribution and then to start using them and concentrate to the assembly programming.
The moderate use of macros does not make your program less assembly written!
The FASM message board is good place to ask questions and to get help, but you have to make your homework after all.
Every running process under windows gets either kernel32 or kernalbase loaded into its address space, using this fact and the PEB internals, you can easily access any windows function (provided you have the right access privileges).
This blog entry details how to go about doing this to display a message with MessageBoxA.
In all honesty, unless you have some extreme reason for doing this, you are going to just end up wasting time, rather use the tools provided (in this case, a linker, so you can access any windows API without going through 10000 hurdles and loops).
I managed to link to one library only (kernel32.dll) and make reference to 3 functions:
GetStdHandle
WriteConsole
ExitProcess
The code below is the result of my exhaustive Google search, and my own reference to MS documentation.
format PE console
entry start
include 'include\win32a.inc'
section '.data' data readable writable
msg db 'Hello World!',13,10,0
len = $-msg
dummy dd ?
section '.code' readable writable executable
start:
push STD_OUTPUT_HANDLE
call [GetStdHandle] ;STD_OUTPUT_HANDLE (DWORD)-11
push 0 ;LPVOID lpReserved
push dummy ;LPDWORD lpNumberOfCharsWritten
push len ;DWORD nNumberOfCharsToWrite
push msg ;VOID *lpBuffer;
push eax ;HANDLE hConsoleOutput
call [WriteConsole]
push 0
call [ExitProcess]
section '.idata' data import readable writable
library kernel32,'KERNEL32.DLL'
include 'include\api\kernel32.inc'
Asking google for help: http://board.flatassembler.net/topic.php?t=14034
Trying it out yourself
; Example of 64-bit PE program
format PE64 GUI
entry start
section '.text' code readable executable
start:
sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned
mov r9d,0
lea r8,[_caption]
lea rdx,[_message]
mov rcx,0
call [MessageBoxA]
mov ecx,eax
call [ExitProcess]
section '.data' data readable writeable
_caption db 'Win64 assembly program',0
_message db 'Hello World!',0
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dq RVA _ExitProcess
dq 0
user_table:
MessageBoxA dq RVA _MessageBoxA
dq 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0
Using nasm to compile this hello world (16 bit) code taken from here:
.model tiny
.code
org 100h
main proc
mov ah,9 ; Display String Service
mov dx,offset hello_message ; Offset of message (Segment DS is the right segment in .COM files)
int 21h ; call DOS int 21h service to display message at ptr ds:dx
retn ; returns to address 0000 off the stack
; which points to bytes which make int 20h (exit program)
hello_message db 'Hello, world!$'
main endp
end main