不使用API,创建一个最简单的窗口

[code=C/C++] 

.386

.model flat, stdcall  ;32 bit memory model
option 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

;-------------------------------------------------------------------------------------------------------------------------------------

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

;-------------------------------------------------------------------------------------------------------------------------------------

.code

;比较字符串
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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值