News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

..as strong as its weakest link

Started by hell0, October 03, 2009, 09:45:35 AM

Previous topic - Next topic

hell0

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..

MichaelW

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.
eschew obfuscation

hell0

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.

hell0

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.

Vortex

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.

hell0

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...

Vortex

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

BlackVortex

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.

hell0

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

BlackVortex

#9
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

hell0

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...

BlackVortex

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

BlackVortex

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

hell0

Well,

it is very kind of you...

...for taking the time to complete a request.

thank you...