a point that could have a little clarification is:
invoke StdOut and invoke crt_printf in a console program generate seemingly identical response i.e. display the value of a zero terminated string.
what is the difference between the two instructions?
another spot is about kernell32.lib and kernell32.dll
Quote"an example: if your source code uses the ExitProcess function (which is exported by kernel32.dll) you specify kernel32.lib in your code and the linker will know that ExitProcess is exported by kernel32.dll."
In other words, a linker 'sees' the kernel32.lib in source and figure out two requirements:
(1) the source needs the function ExitProcess.
(2) the kernel32.dll only can 'send' it.
but, can't this dumb linker reach the same conclusion by 'see'ing the invoke ExitProcess instruction in the very source it is trying to help?
i tried to withhold this(kernel32.lib) information from the linker, and the linker's reaction was not all that approving.
it is just an academic curiosity, nothing more than that.
import address table is 'fixed' by the loader at the time of loading. so, where (within the pe file), does the linker save the data that it has gathered so far?
thank you..
Quotewhat is the difference between the two
printf can do much, much more:
http://msdn.microsoft.com/en-us/library/wc7014hz(VS.71).aspx
Quote
In other words, a linker 'sees' the kernel32.lib in source and figure out two requirements:
(1) the source needs the function ExitProcess.
(2) the kernel32.dll only can 'send' it.
but, can't this dump linker reach the same conclusion by 'see'ing the invoke ExitProcess instruction in the very source it is trying to help?
The linker does not "see" the asm source. When ML assembles the source and sees:
includelib \masm32\lib\kernel32.lib
It includes information in the object module that the linker does see, that tells the linker that it needs to link with kernel32.lib.
MichaelW
QuoteThe linker does not "see" the asm source. When ML assembles the source and sees:
yes . . . you are correct.
it is me who is dumb to refer a good linker in poor terms.
Thank you for your almost instant response and the timely correction.
MichaelW..
i had quoted Vortex earlier.
QuoteVortex - an example: if your source code uses the ExitProcess function (which is exported by kernel32.dll) you specify kernel32.lib in your code and the linker will know that ExitProcess is exported by kernel32.dll."
Quote.... in your code and the linker will know...
What could be Vortex mean by that?
May be i have taken it out of context !
regards ... to both of you.
Hi hell0,
Let me explain with the same example using an extra function named MessageBox :
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\msvcrt.lib
.data
message1 db "This is a printf test.",0
message2 db "This is a MessageBox test.",0
caption db "Hello",0
format1 db "%s",0
.code
start:
invoke crt_printf,ADDR format1,ADDR message1
invoke MessageBox,0,ADDR message2,ADDR caption,MB_OK
invoke ExitProcess,0
END start
The example above has three external functions. crt_printf, MessageBox and ExitProcess are exported by three different DLLs :
- printf which is defined as crt_printf in msvcrt.inc is exported by msvcrt.dll
- MessageBox is exported by user32.dll
- The last ExitProcess is exported by kernel32.dll
Now, the linker does not have any information about those three API functions above. There are a lot of DLLs on your operating system and they have thousands of exported functions. It's not the job of the linker to maintain the information of exported functions so some extra files in the source code, the import libraries will inform the linker about the association of the APIs with the DLLs. kernel32.lib has a list of functions exported by kernel32.dll The same applies also for user32.lib and msvcrt.lib The linker will read the three import libraries and will find the connection between printf and msvcrt.dll , MessageBox - user32.dll and finally ExitProcess - kernel32.dll
There is a tool named dumpbin in the Masm32 installation. This tool can give you the list of APIs from any import library. For example, if you wish to see the functions in kernel32.dll, you have to examine kernel32.lib with dumpbin :
At the command prompt :
\masm32\bin\dumpbin /EXPORTS \masm32\lib\kernel32.lib
You will get a very long list as kernel32.dll exports a lot of functions. Notice that you will see symbols like _ExitProcess@4 , this is a name decoration system utilized by Microsoft tools.
\masm32\bin\dumpbin /EXPORTS C:\Windows\System32\kernel32.dll
This one will target directly kernel32.dll to retrieve the list of functions. You may ask why the linker does not access directly the DLLs to resolve external functions instead of reading import libraries. Golink another very powerful linker by Jeremy Gordon does that exactly, it reads the DLLs. MS link can process static libraries and it's designed to support some specific C++ features like name decoration adopted by MS tools.
Vortex...
that was very endearing...lot of information.
QuoteGolink another very powerful linker by Jeremy Gordon
iam slightly familiar with the linker Golink. Infact, Goasm and Golink were used to assemble and link my first asm program.
Meanwhile, reading your post, i did a window program.
.386
.model flat,stdcall
option casemap:none
include bb.inc
.data
caption db " Beginning MZ exe signature ",0
text db " Header Relocation at 3C:dword",0
mb_ok equ 0
hwnd equ 0
.code
start:
invoke MessageBox,hwnd,addr text,addr caption,mb_ok
invoke ExitProcess,0
end start
And dumped to hex
00000000: 4d 5a 90 00 03 00 00 00 - 04 00 00 00 ff ff 00 00 MZ...... ........
00000010: b8 00 00 00 00 00 00 00 - 40 00 00 00 00 00 00 00 ........ ........
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ........ ........
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 80 00 00 00 ........ ........
00000040: 0e 1f ba 0e 00 b4 09 cd - 21 b8 01 4c cd 21 54 68 ........ ...L..Th
00000050: 69 73 20 70 72 6f 67 72 - 61 6d 20 63 61 6e 6e 6f is.progr am.canno
00000060: 74 20 62 65 20 72 75 6e - 20 69 6e 20 44 4f 53 20 t.be.run .in.DOS.
00000070: 6d 6f 64 65 2e 0d 0d 0a - 24 00 00 00 00 00 00 00 mode.... ........
00000080: 50 45 00 00 4c 01 02 00 - 16 6f c7 4a 00 00 00 00 PE..L... .o.J....
00000090: 00 00 00 00 e0 00 0f 01 - 0b 01 02 32 00 02 00 00 ........ ...2....
where one could see the famous 'MZ'exe signature at the beginning. At 3C the dword 00000080 points to the address of the beginning of the PE header. There, one can see> 50 40 < the ASCII representation for 'PE'. So, what is created is a PE file.
Now, the aim of this whole exercise is to consider the feasibility of writing a small program in masm, which goes through checking all the above mentioned stages and finally displays the conclusion in a message Box. it is/it is not a PE file !!.
it is a toy program for the accomplished but it could be an achievement for one like me. Any suggestions, tips would be valued.
thank you...
Hi hell0,
Have a look at Iczelion's Portable Executable tutorial set :
Tutorial 2: Detecting a Valid PE File
http://win32assembly.online.fr/pe-tut2.html
You should use includes for constants like MB_OK, and just use NULL in your MessageBox instead of declaring hwnd as 0 !
And, well, simple validation of a PE is only a matter of opening it and checking a few bytes.
BlackVortex...
QuoteYou should use includes for constants like MB_OK, and just use
NULL in your MessageBox instead of declaring hwnd as 0! .
thank you for pointing out the irregularity.
yes, iam aware of it. it is used that way (by me) in tasm. it helps to 'see' what parameters am i pushing to the stack and in what order. i simply wanted to check if 'that way' is compatible to masm.
Regards...
Quote
I was kinda bored and I created a goasm example, using WINAPI :
#dynamiclinkfile kernel32.dll user32.dll ; I declare the libraries here, so I don't have to pass them as parameters to the linker
#include windows.h ; This is the main header and includes most or all of the other includes, no nothing else is needed
DATA SECTION
sz_Title db "Test",0
sz_text db "Hello world !",0
temp dd 0
CODE SECTION
START: ; This is the default label used as an entry point to the program, for the linker
invoke GetStdHandle, STD_OUTPUT_HANDLE ; If the program is linked as a console, it will automatically start with an assigned command window, so I go ahead and get its output handle of the screen buffer
invoke WriteConsole, EAX, addr sz_text, 13, addr temp, NULL ; I directly write to the active console screen buffer I just got
invoke MessageBox, NULL, addr sz_text, addr sz_Title, MB_OK ; I also put a messagebox, so the proggy pauses and I can see the console, even if it's not run from cmd prompt
invoke ExitProcess, NULL
BlackVortex...
it is an optimistic gesture.
but the code and its intended outcome is a little hazy for me right now. but, i would love to understand it, especially the use of
#dynamiclinkfile kernel32.dll user32.dll part of it.
So, it would be helpful if you could supplement it with comments, so that i could try and even draw benefit from your endeavor.
meanwhile, considering your enthusiasm, iam encouraged to make a request.
please make a window program in masm that 'gets user input'. something like:
Printf("enter a digit !");
Scanf ("%d",dgt);
Printf("the number you entered is..");
i would like to learn it.
in case, you find enough time and patience to do such a basic material, please remember to be lavish with plain comments.
thank you.
Regards...
That code is GoAsm code, not masm, so don't get confused by those statements. I will edit that post and add some comments right now. It's easy to convert it to masm, you only need to add some red-tape includes and any other directives. I just wanted to show that GoAsm is easier to use and doesn't need all that beaurocracy. Looks good, huh ? :thumbu
If I can make a good (masm) example of what you asked I will, otherwise maybe someone else will do it, or you can give it a shot and if you fail, make a new thread. Next time, please name your threads better, though :P
I wrote a proggy for console input and output. First time I do it in simple WINAPI. It's in GoAsm, but it's very easy to convert to masm :
#dynamiclinkfile kernel32.dll user32.dll
#include windows.h
DATA SECTION
sz_Title db "Test",0
sz_text db "What you typed is in the MsgBox !",0
h_console_out dd 0
h_console_in dd 0
temp dd 0
buffer db 32 dup 0
CODE SECTION
START:
invoke GetStdHandle, STD_OUTPUT_HANDLE ; we get and save the active output buffer
mov [h_console_out], EAX
invoke GetStdHandle, STD_INPUT_HANDLE ; we get and save the input buffer
mov [h_console_in], EAX
invoke SetConsoleMode, [h_console_in], ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT ; we set console mode to that, check the function's definition for info
invoke ReadConsole, [h_console_in], addr buffer, sizeof(buffer)-4, addr temp, NULL ; this function *waits* for carriage - return'ed input, because we've set it to that mode
; I leave some wiggle room,4 bytes, to be sure there's no overflow
invoke WriteConsole, [h_console_out], addr sz_text, 33, addr temp, NULL ; we write some stuff to the output, I make sure the string is big enough to overwrite the previous contents
invoke MessageBox, NULL, addr buffer, addr sz_Title, MB_OK ; we wanna see what our input buffer contains, so I use MsgBox
invoke ExitProcess, NULL
Well,
it is very kind of you...
...for taking the time to complete a request.
thank you...