My thoughts on Windows ASM

Posts 115 of 25 · Page 1 of 2
My thoughts on Windows ASM
Code:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib            ; calls to functions in user32.lib and kernel32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.DATA                     ; initialized data
ClassName db "SimpleWinClass",0        ; the name of our window class
AppName db "Our First Window",0        ; the name of our window

.DATA?                ; Uninitialized data
hInstance HINSTANCE ?        ; Instance handle of our program
CommandLine LPSTR ?
.CODE                ; Here begins our code
start:
invoke GetModuleHandle, NULL            ; get the instance handle of our program.
                                                                       ; Under Win32, hmodule==hinstance mov hInstance,eax
mov hInstance,eax
invoke GetCommandLine                        ; get the command line. You don't have to call this function IF
                                                                       ; your program doesn't process the command line.
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        ; call the main function
invoke ExitProcess, eax                           ; quit our program. The exit code is returned in eax from WinMain.

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX                                            ; create local variables on stack
    LOCAL msg:MSG
    LOCAL hwnd:HWND

    mov   wc.cbSize,SIZEOF WNDCLASSEX                   ; fill values in members of wc
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc                       ; register our window class
    invoke CreateWindowEx,NULL,\
                ADDR ClassName,\
                ADDR AppName,\
                WS_OVERLAPPEDWINDOW,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                NULL,\
                NULL,\
                hInst,\
                NULL
    mov   hwnd,eax
    invoke ShowWindow, hwnd,CmdShow               ; display our window on desktop
    invoke UpdateWindow, hwnd                                 ; refresh the client area

    .WHILE TRUE                                                         ; Enter message loop
                invoke GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                invoke TranslateMessage, ADDR msg
                invoke DispatchMessage, ADDR msg
   .ENDW
    mov     eax,msg.wParam                                            ; return exit code in eax
    ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY                           ; if the user closes our window
        invoke PostQuitMessage,NULL             ; quit our application
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam     ; Default message processing
        ret
    .ENDIF
    xor eax,eax
    ret
WndProc endp

end start
That was the last tutorial I did... it reminds me strangely of C++ Windows programming. Oh yeh... that's cuz it is windows programming, almost entirely. I expected asm to be more instruction oriented, but I'm not discouraged. I wanted to learn more about Windows anyway. And what is the best way to understand Windows then at it's lowest level. (I know there's kernel memory... just go with it for now k )

I figure What I'll do is follow Iczelion's tutorials and then view the Disassembly of each program. I also found this Tutorial by someone named Exagone that explain more of the traditional asm: Exagone's Tut
I think I will add this to the main tutorial which has been in shambles due to no one knowing what they are doing, and those who do not giving a shit. (excuse my language). This is Exagone's introduction. It may give you a feel for how his tutorial is different then others.
Quote Originally Posted by Exagone's Introduction
Introduction

First a short introduction about this tutorial. Win32asm isn't a very popular programming language, and there are only a few (good) tutorials. Also, most tutorials focus on the win32 part of the programming (i.e. the win API, use of standard windows programming techniques and so on), not on the assembler programming itself, using opcodes, registers etc. Although you can find these things in other tutorials, these tutorials often explain DOS programming. This sure helps you to learn the assembly language, but with programming in windows, you don't need to know about DOS interrupts and port in/out functions. In windows, there's the windows API that supplies standard functions you can use in your program, but more on this later. The goal of this tutorial is to explain win32 programming in assembler as well as assembly language itself.
And here is the Dissassembly again. This one is much more impressive then last time.
Code:
00401000 >/$ 6A 00          PUSH 0                                   ; /pModule = NULL
00401002  |. E8 A7010000    CALL <JMP.&kernel32.GetModuleHandleA>    ; \GetModuleHandleA
00401007  |. A3 44304000    MOV DWORD PTR DS:[403044],EAX
0040100C  |. E8 97010000    CALL <JMP.&kernel32.GetCommandLineA>     ; [GetCommandLineA
00401011  |. A3 48304000    MOV DWORD PTR DS:[403048],EAX
00401016  |. 6A 0A          PUSH 0A                                  ; /Arg4 = 0000000A
00401018  |. FF35 48304000  PUSH DWORD PTR DS:[403048]               ; |Arg3 = 00000000
0040101E  |. 6A 00          PUSH 0                                   ; |Arg2 = 00000000
00401020  |. FF35 44304000  PUSH DWORD PTR DS:[403044]               ; |Arg1 = 00000000
00401026  |. E8 06000000    CALL MyFirstA.00401031                   ; \MyFirstA.00401031
0040102B  |. 50             PUSH EAX                                 ; /ExitCode
0040102C  \. E8 71010000    CALL <JMP.&kernel32.ExitProcess>         ; \ExitProcess
00401031  /$ 55             PUSH EBP
00401032  |. 8BEC           MOV EBP,ESP
00401034  |. 83C4 B0        ADD ESP,-50
00401037  |. C745 D0 300000>MOV DWORD PTR SS:[EBP-30],30
0040103E  |. C745 D4 030000>MOV DWORD PTR SS:[EBP-2C],3
00401045  |. C745 D8 191140>MOV DWORD PTR SS:[EBP-28],MyFirstA.00401>
0040104C  |. C745 DC 000000>MOV DWORD PTR SS:[EBP-24],0
00401053  |. C745 E0 000000>MOV DWORD PTR SS:[EBP-20],0
0040105A  |. FF35 44304000  PUSH DWORD PTR DS:[403044]
00401060  |. 8F45 E4        POP DWORD PTR SS:[EBP-1C]
00401063  |. C745 F0 060000>MOV DWORD PTR SS:[EBP-10],6
0040106A  |. C745 F4 000000>MOV DWORD PTR SS:[EBP-C],0
00401071  |. C745 F8 003040>MOV DWORD PTR SS:[EBP-8],MyFirstA.004030>;  ASCII "SimpleWinClass"
00401078  |. 68 007F0000    PUSH 7F00                                ; /RsrcName = IDI_APPLICATION
0040107D  |. 6A 00          PUSH 0                                   ; |hInst = NULL
0040107F  |. E8 F4000000    CALL <JMP.&user32.LoadIconA>             ; \LoadIconA
00401084  |. 8945 E8        MOV DWORD PTR SS:[EBP-18],EAX
00401087  |. 8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
0040108A  |. 68 007F0000    PUSH 7F00                                ; /RsrcName = IDC_ARROW
0040108F  |. 6A 00          PUSH 0                                   ; |hInst = NULL
00401091  |. E8 DC000000    CALL <JMP.&user32.LoadCursorA>           ; \LoadCursorA
00401096  |. 8945 EC        MOV DWORD PTR SS:[EBP-14],EAX
00401099  |. 8D45 D0        LEA EAX,DWORD PTR SS:[EBP-30]
0040109C  |. 50             PUSH EAX                                 ; /pWndClassEx
0040109D  |. E8 E8000000    CALL <JMP.&user32.RegisterClassExA>      ; \RegisterClassExA
004010A2  |. 6A 00          PUSH 0                                   ; /lParam = NULL
004010A4  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hInst
004010A7  |. 6A 00          PUSH 0                                   ; |hMenu = NULL
004010A9  |. 6A 00          PUSH 0                                   ; |hParent = NULL
004010AB  |. 68 00000080    PUSH 80000000                            ; |Height = 80000000 (-2147483648.)
004010B0  |. 68 00000080    PUSH 80000000                            ; |Width = 80000000 (-2147483648.)
004010B5  |. 68 00000080    PUSH 80000000                            ; |Y = 80000000 (-2147483648.)
004010BA  |. 68 00000080    PUSH 80000000                            ; |X = 80000000 (-2147483648.)
004010BF  |. 68 0000CF00    PUSH 0CF0000                             ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION
004010C4  |. 68 0F304000    PUSH MyFirstA.0040300F                   ; |WindowName = "My First Asm Window"
004010C9  |. 68 00304000    PUSH MyFirstA.00403000                   ; |Class = "SimpleWinClass"
004010CE  |. 6A 00          PUSH 0                                   ; |ExtStyle = 0
004010D0  |. E8 85000000    CALL <JMP.&user32.CreateWindowExA>       ; \CreateWindowExA
004010D5  |. 8945 B0        MOV DWORD PTR SS:[EBP-50],EAX
004010D8  |. FF75 14        PUSH DWORD PTR SS:[EBP+14]               ; /ShowState
004010DB  |. FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; |hWnd
004010DE  |. E8 AD000000    CALL <JMP.&user32.ShowWindow>            ; \ShowWindow
004010E3  |. FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; /hWnd
004010E6  |. E8 B1000000    CALL <JMP.&user32.UpdateWindow>          ; \UpdateWindow
004010EB  |> 6A 00          /PUSH 0                                  ; /MsgFilterMax = 0
004010ED  |. 6A 00          |PUSH 0                                  ; |MsgFilterMin = 0
004010EF  |. 6A 00          |PUSH 0                                  ; |hWnd = NULL
004010F1  |. 8D45 B4        |LEA EAX,DWORD PTR SS:[EBP-4C]           ; |
004010F4  |. 50             |PUSH EAX                                ; |pMsg
004010F5  |. E8 72000000    |CALL <JMP.&user32.GetMessageA>          ; \GetMessageA
004010FA  |. 0BC0           |OR EAX,EAX
004010FC  |. 74 14          |JE SHORT MyFirstA.00401112
004010FE  |. 8D45 B4        |LEA EAX,DWORD PTR SS:[EBP-4C]
00401101  |. 50             |PUSH EAX                                ; /pMsg
00401102  |. E8 8F000000    |CALL <JMP.&user32.TranslateMessage>     ; \TranslateMessage
00401107  |. 8D45 B4        |LEA EAX,DWORD PTR SS:[EBP-4C]
0040110A  |. 50             |PUSH EAX                                ; /pMsg
0040110B  |. E8 56000000    |CALL <JMP.&user32.DispatchMessageA>     ; \DispatchMessageA
00401110  |.^EB D9          \JMP SHORT MyFirstA.004010EB
00401112  |> 8B45 BC        MOV EAX,DWORD PTR SS:[EBP-44]
00401115  |. C9             LEAVE
00401116  \. C2 1000        RETN 10
00401119  /. 55             PUSH EBP
0040111A  |. 8BEC           MOV EBP,ESP
0040111C  |. 837D 0C 02     CMP DWORD PTR SS:[EBP+C],2
00401120  |. 75 1D          JNZ SHORT MyFirstA.0040113F
00401122  |. 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
00401124  |. 68 23304000    PUSH MyFirstA.00403023                   ; |Title = "Noooo!!!"
00401129  |. 68 2C304000    PUSH MyFirstA.0040302C                   ; |Text = "Don't Kill me! Why?!"
0040112E  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
00401131  |. E8 48000000    CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
00401136  |. 6A 00          PUSH 0                                   ; /ExitCode = 0
00401138  |. E8 47000000    CALL <JMP.&user32.PostQuitMessage>       ; \PostQuitMessage
0040113D  |. EB 15          JMP SHORT MyFirstA.00401154
0040113F  |> FF75 14        PUSH DWORD PTR SS:[EBP+14]               ; /lParam
00401142  |. FF75 10        PUSH DWORD PTR SS:[EBP+10]               ; |wParam
00401145  |. FF75 0C        PUSH DWORD PTR SS:[EBP+C]                ; |Message
00401148  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
0040114B  |. E8 10000000    CALL <JMP.&user32.DefWindowProcA>        ; \DefWindowProcA
00401150  |. C9             LEAVE
00401151  |. C2 1000        RETN 10
00401154  |> 33C0           XOR EAX,EAX
00401156  |. C9             LEAVE
00401157  \. C2 1000        RETN 10
0040115A   $-FF25 3C204000  JMP DWORD PTR DS:[<&user32.CreateWindowE>;  user32.CreateWindowExA
00401160   $-FF25 34204000  JMP DWORD PTR DS:[<&user32.DefWindowProc>;  user32.DefWindowProcA
00401166   $-FF25 30204000  JMP DWORD PTR DS:[<&user32.DispatchMessa>;  user32.DispatchMessageA
0040116C   $-FF25 20204000  JMP DWORD PTR DS:[<&user32.GetMessageA>] ;  user32.GetMessageA
00401172   $-FF25 10204000  JMP DWORD PTR DS:[<&user32.LoadCursorA>] ;  user32.LoadCursorA
00401178   $-FF25 14204000  JMP DWORD PTR DS:[<&user32.LoadIconA>]   ;  user32.LoadIconA
0040117E   $-FF25 18204000  JMP DWORD PTR DS:[<&user32.MessageBoxA>] ;  user32.MessageBoxA
00401184   $-FF25 1C204000  JMP DWORD PTR DS:[<&user32.PostQuitMessa>;  user32.PostQuitMessage
0040118A   $-FF25 38204000  JMP DWORD PTR DS:[<&user32.RegisterClass>;  user32.RegisterClassExA
00401190   $-FF25 24204000  JMP DWORD PTR DS:[<&user32.ShowWindow>]  ;  user32.ShowWindow
00401196   $-FF25 28204000  JMP DWORD PTR DS:[<&user32.TranslateMess>;  user32.TranslateMessage
0040119C   $-FF25 2C204000  JMP DWORD PTR DS:[<&user32.UpdateWindow>>;  user32.UpdateWindow
004011A2   .-FF25 04204000  JMP DWORD PTR DS:[<&kernel32.ExitProcess>;  kernel32.ExitProcess
004011A8   $-FF25 00204000  JMP DWORD PTR DS:[<&kernel32.GetCommandL>;  kernel32.GetCommandLineA
004011AE   $-FF25 08204000  JMP DWORD PTR DS:[<&kernel32.GetModuleHa>;  kernel32.GetModuleHandleA
I will post this here for now, because unfortunately I ran out of time to study it any further. I reccommend anyone else who is studying asm make use of the help file I posted. The end goal is of course to be able to quickly read through disassembly so I must be steadfast in this.
Exagone's tutorial.rarattachment deleted · 6 downloads before removal
Damn Why06, you're learning fast. Great job by the way.
Quote Originally Posted by Void View Post
Damn Why06, you're learning fast. Great job by the way.
Lol. Not really. It's going to take me all day to figure out this disassembly. When I do I'll post the explanation.
I somewhat understand it, with the exception of a few instructions. Like, 'RETN 10' (What does 10 signify?) , 'Leave' , and a few complications with jumping.
Quote Originally Posted by Void View Post
I somewhat understand it, with the exception of a few instructions. Like, 'RETN 10' (What does 10 signify?) , 'Leave' , and a few complications with jumping.
Me too. I'd also like to get this JMP DWORD PTR DS: OFFSET which looks a lot like 16 bit asm, which to be honest really confuses me.

Anyway the file I included seems to go over the other functions... I'll see how far I get.
Quote Originally Posted by why06 View Post
Me too. I'd also like to get this JMP DWORD PTR DS: OFFSET which looks a lot like 16 bit asm, which to be honest really confuses me.

Anyway the file I included seems to go over the other functions... I'll see how far I get.
jump to the dword pointer ds + offset?
i believe all 2 character registers(if im allowed to call them that) are for pointers etc(not sure tho, I suck at asm)
It really is just as it says:
Jump to 'Offset' which is defined as a DWORD (and it's a pointer obviously) in the DataSegment..
In windows you dont really deal with different segments (because of the 'flat' memory model), so you can safely ignore it. So really it's just stating that whatever you're jumping to is a 'dword'

e.g. If you had EAX being 1234ABCD
A DWord pointer would jump to 1234ABCD
but a WORD pointer would jump to 1234
and Byte Pointer would jump to 12
(if I remember correctly ) been a while since I've dealt with that..
Double words in 16bit assembly? xD

16 bit assembly also confuses me.
Well I think a dword, word, and byte pointer would all jump to the same memory location:
dword ptr [1234ABCDh]
byte ptr [1234ABCDh]
word ptr [1234ABCDh]

The once it gets to that memory location:

0x1234ABCD lets make this 0x0000 0006 (for this example) lets say 1234ABCD is the value stored there. for this example's sake

... diagram of memory from high to low
low .... 06 07 08 09 ... high (in bytes) - pretending this is the memory location of 0x1234ABCD
.......... CD AB 34 12 .... ....

So to elaborate on ur point BA. it would jump to the memory location , but retrieve the smallest value of 1234ABCD first which would CD if it was a byte pointer. ABCD if it was a word. Correct me if I'm wrong. But I like the way little endian works. It's a little confusing in memory, but it makes more since when coding.

I was also wondering how to find out what DS is in a debugger, It's supposed to mean data segment, but If I wanted to find the address DS say so I could change it. Would it be worth it. Or would DS possibly change next time I load up the program, because it's dynamically allocated. In that case how would I get DS in say C++ code?
You're right - my sample was backwards (that's what I get for working on to many different platforms lol) And you're also seeing why little endian is so popular in computer architecture . makes is easy to calculate stuff etc

the *SIZE* PTR works with jmps and move's:
Code:
mov eax, 12345678h
jmp DWORD PTR eax     ;jmp to 12345678
jmp WORD PTR eax       ; jmp to 5678
mov bl, BYTE PTR eax  ; bl now hold 78
ofcourse in disassembly instead of 'eax' you'll most likely see ds:[458448] or some other address pointer which really is just like a function pointer in C++
"Jump to whatever address is stored in 458448 and it's a 'byte/word/dword' value"


to address david's Q

RetN is 'return near' which pops the top of the stack into the (e)IP (Instruction Pointer) (there's also retf, return far. 10 is how many bytes to pop

'Leave' is used in combination with 'enter' which in fact is a alternate efor the default stack frame commands : push ebp, move ebp,esp

you'll see:
enter 8,0
.
.
leave
ret

which allocates 8 bytes on the stack for local variables, and then leave clears those
BA.. im sure u mean well, but u really must stop giving out this advice to people learning when you are 100% wrong.. there is no such thing as JMP word ptr eax.. neither is there JMP byte ptr eax when dealing with 32bit architecture.. for starters.. if you want to reference ANYTHING you need to [bracket] it.. so its [eax] not eax... and the only BYTE and WORD references pertaining to 32 architecture is as why06 has already explained.. they are REFERENCING different data types.. /32bit reference = mov eax,dword ptr [eax]/16bit reference = mov eax,word ptr [eax]/8bit reference = movzx eax,byte ptr [eax].. it makes things a lot harder when the blind are being lead by the blinder.
Quote Originally Posted by [sheep] View Post
BA.. im sure u mean well, but u really must stop giving out this advice to people learning when you are 100% wrong.. there is no such thing as JMP word ptr eax.. neither is there JMP byte ptr eax when dealing with 32bit architecture.. for starters.. if you want to reference ANYTHING you need to [bracket] it.. so its [eax] not eax... and the only BYTE and WORD references pertaining to 32 architecture is as why06 has already explained.. they are REFERENCING different data types.. /32bit reference = mov eax,dword ptr [eax]/16bit reference = mov eax,word ptr [eax]/8bit reference = movzx eax,byte ptr [eax].. it makes things a lot harder when the blind are being lead by the blinder.
I'm sure what BA posted wasn't intended to be a working piece of assembly, it serves as a reference as to how BYTE, WORD and DWORD works...

And I'm sure the brackets are IDE specific...
You should be careful with your words. It might have been a while since BA has done some serious Disassembly, but I certainly wouldn't call him blind. He is a wizard at MASM, C#, C++, MFC, Java, Windows API, etc. I could probably list more languages he knows well then you've ever heard of. He's the most experienced coder here, and I would appreciate it if you would be respectful of that, before you go killing him on one mistake. ;l
Sigh!! the brackets are x86 specific.. it has absolutely nothing to do with the IDE.. I say it how i see it.. and considering ive written hacks and tools for pretty much every platform there is .. including.. megadrive,snes,amiga, atari st, xbox,psp, nds, gba, iphone,pc of course.. and to my knoweldge im currently the only person to have a properly and full functional ingame trainer for the WII.. (check out sheepthehack on youtube) and i was the second person to release a working XBOX trainer (beaten narrowly by crazy nation mainly cus they are a incredible smart guys).. hmmm languages.. c,C++, asm, mips, arm, 68000...the list is long.. not because im clever.. but because if ur around long enuff one language becomes as easy to pick up as the next.. and even though that makes me look like a gigantic prick.. you can ask me advice on ANY of those subjects above and i will give you 100% complete and accurate information.. because if i didnt.. then im misleading.. THATS!! why i called him blind. sorry that i offended your friend.. not my intention. just because someone knows more than u.. dont assume he knows more than everyone else.
Quote Originally Posted by [sheep] View Post
Sigh!! the brackets are x86 specific.. it has absolutely nothing to do with the IDE.. I say it how i see it.. and considering ive written hacks and tools for pretty much every platform there is .. including.. megadrive,snes,amiga, atari st, xbox,psp, nds, gba, iphone,pc of course.. and to my knoweldge im currently the only person to have a properly and full functional ingame trainer for the WII.. (check out sheepthehack on youtube) and i was the second person to release a working XBOX trainer (beaten narrowly by crazy nation mainly cus they are a incredible smart guys).. hmmm languages.. c,C++, asm, mips, arm, 68000...the list is long.. not because im clever.. but because if ur around long enuff one language becomes as easy to pick up as the next.. and even though that makes me look like a gigantic prick.. you can ask me advice on ANY of those subjects above and i will give you 100% complete and accurate information.. because if i didnt.. then im misleading.. THATS!! why i called him blind. sorry that i offended your friend.. not my intention. just because someone knows more than u.. dont assume he knows more than everyone else.
Quoted from B1ackAnge1: 'Life observation: People who proclaim the loudest how good they are usually are pretty crappy at what they do.'

Quote Originally Posted by B1ackAnge1
I still like WinAsm better (UI For Masm32)

Comparing between masm & fasm

Loading an address:

● Equivalent syntax in MASM: mov eax,offset memvar
● Equivalent syntax in FASM: mov eax,memvar

Loading a value:

● Equivalent syntax in MASM: mov eax,memvar
● Equivalent syntax in FASM: mov eax,[memvar]
the brackets weren't IDE specific you said?
Posts 115 of 25 · Page 1 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?