[code=C/C++]
.386
.model flat, stdcall ;32 bit memory modeloption casemap :none ;case sensitive
include windows.inc
;-------------------------------------------------------------------------------------------------------------------------------------
.data
g_hInst dd 0
g_hWnd dd 0
g_kernel32 dd 0
g_user32 dd 0
g_LoadLib dd 0
g_FreeLib dd 0
g_RegClassEx dd 0
g_CreateWindow dd 0
g_ShowWindow dd 0
g_UpdateWindow dd 0
g_GetMessage dd 0
g_TransMsg dd 0
g_DispatchMsg dd 0
g_GetModuleHandle dd 0
g_DefWindowProc dd 0
g_PostQuitMsgdd 0
;-------------------------------------------------------------------------------------------------------------------------------------
g_szClsName db 'hello',0
g_szUser32 db 'user32.dll', 0
g_szMsgBox db 'MessageBoxA', 0
g_szLoadLib db 'LoadLibraryA',0
g_szFreeLib db 'FreeLibrary',0
g_szRegClassEx db 'RegisterClassExA',0
g_szCreateWindow db 'CreateWindowExA',0
g_szShowWindow db 'ShowWindow',0
g_szUpdateWindow db 'UpdateWindow',0
g_szGetMessage db 'GetMessageA',0
g_szTransMsg db 'TranslateMessage',0
g_szDispatchMsg db 'DispatchMessageA',0
g_szGetModuleHandle db 'GetModuleHandleA',0
g_szDefWindowProc db 'DefWindowProcA',0
g_szPostQuitMsgdb 'PostQuitMessage',0
;-------------------------------------------------------------------------------------------------------------------------------------
;比较字符串
StringCmp proc uses ecx edi esi dest,src
LOCAL @StrSrcLen ;Src串长度
xor ecx,ecx ;获取Src串长度,包括 /0
mov esi,src
GetStrLen_Start:
cmp byte ptr[esi + ecx],0
je GetStrLen_Exit
inc ecx
jmp GetStrLen_Start
GetStrLen_Exit:
.if ecx == 0
mov eax, -1
ret
.endif
mov @StrSrcLen,ecx
inc @StrSrcLen
xor ecx,ecx
.while ecx != @StrSrcLen
mov edi,dest
mov esi,src
mov ah,byte ptr [edi + ecx]
mov al,byte ptr [esi + ecx]
;mov ah,byte ptr [dest + ecx]
;mov al,byte ptr [src + ecx]
sub ah,al
.if ah != 0
ret
.endif
inc ecx
.endw
xor eax,eax
ret
StringCmp endp
;-------------------------------------------------------------------------------------------------------------------------------------
;窗口过程
WndProc proc hWnd,msg,wParam,lParam
.if msg == WM_DESTROY
push 0
call g_PostQuitMsg
.else
;DefWindowProc(hWnd, message, wParam, lParam);
push lParam
push wParam
push msg
push hWnd
call g_DefWindowProc
ret
.endif
xor eax,eax
ret
WndProc endp
;注册窗口
MyRegisterClass proc hInst
LOCAL wcex:WNDCLASSEX
mov wcex.cbSize,sizeof WNDCLASSEX
mov wcex.style,CS_HREDRAW or CS_VREDRAW
mov wcex.lpfnWndProc,WndProc
mov wcex.cbClsExtra,0
mov wcex.cbWndExtra,0
mov eax,g_hInst
mov wcex.hInstance,eax
mov wcex.hIcon,0
mov wcex.hCursor,0
mov wcex.hbrBackground,COLOR_WINDOW+1
mov wcex.lpszMenuName,0
mov wcex.lpszClassName,offset g_szClsName
mov wcex.hIconSm,0
lea eax,wcex
push eax
call g_RegClassEx
ret
MyRegisterClass endp
;-------------------------------------------------------------------------------------------------------------------------------------
;获取函数地址
GetProcAddr proc uses ecx ebx esi hModule:dword, FunName:dword
LOCAL @NumberOfNames ;函数名称个数
.if hModule == NULL
xor eax, eax
ret
.endif
mov ebx,hModule
assume ebx:ptr IMAGE_DOS_HEADER
add ebx,[ebx].e_lfanew
assume ebx:ptr IMAGE_NT_HEADERS
lea ebx,[ebx].OptionalHeader.DataDirectory
assume ebx:ptr IMAGE_DATA_DIRECTORY
mov ebx,[ebx].VirtualAddress
add ebx,hModule
assume ebx:ptr IMAGE_EXPORT_DIRECTORY
.if FunName > 0ffffh ;参数是函数名
mov edx,[ebx].AddressOfNames
add edx,hModule
mov eax,[ebx].NumberOfNames
mov @NumberOfNames,eax
xor ecx,ecx
.while ecx != @NumberOfNames ;查找函数名
mov edi,dword ptr[edx + 4*ecx]
add edi,hModule
invoke StringCmp,edi,FunName
.if eax == 0
mov edx,[ebx].AddressOfNameOrdinals
add edx,hModule
movzx eax,word ptr[edx+ecx*2]
jmp GetProcAddr_Exit
.endif
inc ecx
.endw
xor eax,eax
ret
.else ;参数是序号
mov ecx,[ebx].NumberOfFunctions
mov eax,FunName
sub eax,[ebx].nBase
.if eax >= ecx ;序号超出范围
xor eax, eax
ret
.endif
.endif
GetProcAddr_Exit:
mov ebx,[ebx].AddressOfFunctions ;函数地址
add ebx,hModule
mov eax,dword ptr [ebx + 4 * eax]
add eax,hModule
ret
GetProcAddr endp
;-------------------------------------------------------------------------------------------------------------------------------------
;获取kernel32
GetKernel32 proc
assume fs:nothing
mov eax, fs:[18h]
mov eax, [eax+30h]
mov eax, [eax+0ch]
mov eax, [eax+0ch]
mov eax, [eax]
mov eax, [eax]
mov eax, [eax+18h]
ret
GetKernel32 endp
;-------------------------------------------------------------------------------------------------------------------------------------
;显示一个窗口
MyShowWindows proc
LOCAL @msg:MSG
;注册窗口
invoke MyRegisterClass,g_hInst
;创建窗口
push 0
push g_hInst
push 0
push 0
push 0
push CW_USEDEFAULT
push 0
push CW_USEDEFAULT
push WS_OVERLAPPEDWINDOW
mov eax,offset g_szClsName
push eax
mov eax,offset g_szClsName
push eax
push 0
call g_CreateWindow
;hWnd = CreateWindowEx(0,szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
;CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
.if eax == 0
jmp Window_Exit
.endif
mov g_hWnd,eax
;ShowWindow(hWnd, nCmdShow);
;显示窗口
push SW_SHOWNORMAL
push g_hWnd
call g_ShowWindow
;UpdateWindow(hWnd);
;更新窗口
push g_hWnd
call g_UpdateWindow
; while (GetMessage(&msg, NULL, 0, 0))
; {
; TranslateMessage(&msg);
; DispatchMessage(&msg);
; }
;消息循环
;GetMessage(&msg, NULL, 0, 0)
push 0
push 0
push 0
lea eax,@msg
push eax
call g_GetMessage
.while eax
;TranslateMessage(&msg)
lea eax,@msg
push eax
call g_TransMsg
;DispatchMessage(&msg)
lea eax,@msg
push eax
call g_DispatchMsg
;GetMessage(&msg, NULL, 0, 0)
push 0
push 0
push 0
lea eax,@msg
push eax
call g_GetMessage
.endw
Window_Exit:
ret
MyShowWindows endp
;--------------------------------------------------------------------------------------------------
start:
invoke GetKernel32
.if eax ==0
jmp Proc_Exit
.endif
mov g_kernel32,eax
invoke GetProcAddr,eax,offset g_szLoadLib
.if eax ==0
jmp Proc_Exit
.endif
mov g_LoadLib,eax
invoke GetProcAddr,g_kernel32,offset g_szGetModuleHandle
.if eax ==0
jmp Proc_Exit
.endif
mov g_GetModuleHandle,eax
push 0 ;获取当前instance
call g_GetModuleHandle
mov g_hInst,eax
push offset g_szUser32 ;获取user32
call g_LoadLib
.if eax ==0
jmp Proc_Exit
.endif
mov g_user32,eax
invoke GetProcAddr,g_user32,offset g_szRegClassEx
.if eax ==0
jmp Proc_Exit
.endif
mov g_RegClassEx,eax
invoke GetProcAddr,g_user32,offset g_szCreateWindow
.if eax ==0
jmp Proc_Exit
.endif
mov g_CreateWindow,eax
invoke GetProcAddr,g_user32,offset g_szShowWindow
.if eax ==0
jmp Proc_Exit
.endif
mov g_ShowWindow,eax
invoke GetProcAddr,g_user32,offset g_szUpdateWindow
.if eax ==0
jmp Proc_Exit
.endif
mov g_UpdateWindow,eax
invoke GetProcAddr,g_user32,offset g_szGetMessage
.if eax ==0
jmp Proc_Exit
.endif
mov g_GetMessage,eax
invoke GetProcAddr,g_user32,offset g_szTransMsg
.if eax ==0
jmp Proc_Exit
.endif
mov g_TransMsg,eax
invoke GetProcAddr,g_user32,offset g_szDispatchMsg
.if eax ==0
jmp Proc_Exit
.endif
mov g_DispatchMsg,eax
invoke GetProcAddr,g_user32,offset g_szDefWindowProc
.if eax ==0
jmp Proc_Exit
.endif
mov g_DefWindowProc,eax
invoke GetProcAddr,g_user32,offset g_szPostQuitMsg
.if eax ==0
jmp Proc_Exit
.endif
mov g_PostQuitMsg,eax
invoke MyShowWindows
Proc_Exit:
ret
end start
[/code]