.386
.model flat,stdcall
option casemap:none
assume fs:nothing
;[+0] 本模块实例句柄
;[+4] kernel32.dll 模块基址
;[+8] GetProcAddress 函数地址
;[+0Ch] LoadLibraryA 函数地址
;[+10h] user32.dll 模块基址
;[+14h] ClassName
;[+18h]~[+3Ch] WNDCLASSA 结构体
;[+40h] RegisterClassA 函数地址
;[+44h] DefWindowProcA 函数地址
;[+48h] CreateWindowExA 函数地址
;[+4Ch] GetMessageA 函数地址
;[+50h] DispatchMessageA 函数地址
;[+54h]~[+60h] MSG 结构体
;[+64h] 窗口句柄
.code
main:
push ebp
mov ebp,esp
call GetGlobal
mov edi,eax
;----------------------------------------------------
;mov ebx,fs:[30h]
mov ebx,[ebx+0Ch]
mov ebx,[ebx+0Ch]
mov edx,[ebx+18h]
mov [edi],edx ;[+0]保存本模块实例句柄
mov ebx,[ebx]
mov ebx,[ebx]
mov ebx,[ebx+18h]
mov [edi+4],ebx ;[+4]保存kernel32.dll模块基址
mov eax,[ebx+3Ch] ;取Nt头文件偏移
add eax,ebx ;offset=>VA
mov eax,[eax+78h] ;取导出表RVA
add eax,ebx ;RVA=>VA
mov edx,[eax+20h] ;取名称表RVA
add edx,ebx ;RVA=>VA
xor ecx,ecx ;ecx清零
MyLoop:
mov esi,[edx+ecx*4] ;取函数名RVA
add esi,ebx ;RVA=>VA
inc ecx ;ecx++
cmp byte ptr[esi],'G' ;如果等于ZF会被置为1
jnz MyLoop ;ZF为0则跳转
cmp byte ptr[esi+3],'P'
jnz MyLoop
cmp byte ptr[esi+7],'A'
jnz MyLoop
dec ecx ;ecx-- 真正的下标
mov edx,[eax+24h] ;取序号表RVA
add edx,ebx ;RVA=>VA
mov cx,[edx+ecx*2] ;通过序号表找到地址表下标
mov edx,[eax+1Ch] ;取地址表RVA
add edx,ebx ;RVA=>VA
mov esi,[edx+ecx*4] ;取函数RVA
add esi,ebx ;RVA=>VA
mov [edi+8],esi ;保存GetProcAddress函数地址
call PushStr1 ;将下面的数据地址入栈
db "LoadLibraryA",0 ;参数2:要获取的函数名
PushStr1:
push ebx ;参数1:kernel32.dll模块基址
call esi ;GetProcAddress
mov [edi+0Ch],eax ;保存LoadLibraryA函数地址
call PushStr2 ;将下面的数据地址入栈
db "user32.dll",0 ;参数1:需要Load的DLL名称
PushStr2:
call eax ;LoadLibraryA
mov [edi+10h],eax ;保存user32.dll模块基址
mov dword ptr[edi+14h],434241h ;ClassName "ABC"
mov dword ptr[edi+18h],0 ;style
mov dword ptr[edi+1Ch],WndProc ;lpfnWndProc
mov dword ptr[edi+20h],0 ;cbClsExtra
mov dword ptr[edi+24h],0 ;cbWndExtra
mov edx,[edi] ;取实例句柄
mov dword ptr[edi+28h],edx ;hInstance
mov dword ptr[edi+2Ch],0 ;hIcon
mov dword ptr[edi+30h],0 ;hCursor
mov dword ptr[edi+34h],0 ;hbrBackground
mov dword ptr[edi+38h],0 ;lpszMenuName
lea edx,[edi+14h] ;取字符串地址
mov dword ptr[edi+3Ch],edx ;lpszClassName
call PushStr3 ;将下面的数据地址入栈
db "RegisterClassA",0 ;参数2:要获取的函数名
PushStr3:
push [edi+10h] ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov [edi+40h],eax ;保存RegisterClassA函数地址
lea edx,[edi+18h] ;取WNDCLASSA结构体地址
push edx ;参数1:&WNDCLASSA
call eax ;RegisterClassA
call PushStr4 ;将下面的数据地址入栈
db "DefWindowProcA",0 ;参数2:要获取的函数名
PushStr4:
push [edi+10h] ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov [edi+44h],eax ;保存DefWindowProcA函数地址
call PushStr5 ;将下面的数据地址入栈
db "CreateWindowExA",0 ;参数2:要获取的函数名
PushStr5:
push [edi+10h] ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov [edi+48h],eax ;保存CreateWindowExA函数地址
push 0 ;lpParam
push [edi] ;hInstance
push 0 ;hMenu
push 0 ;hWndParent
push 200 ;nHeight
push 400 ;nWidth
push 0 ;Y
push 0 ;X
push 10080000h ;dwStyle
push 0 ;lpWindowName
lea edx,[edi+14h] ;取字符串地址
push edx ;lpClassName
push 00000010h ;dwExStyle
call eax ;CreateWindowExA
mov [edi+64h],eax ;保存窗口句柄
call CreateControl ;创建控件
call PushStr6 ;将下面的数据地址入栈
db "GetMessageA",0 ;参数2:要获取的函数名
PushStr6:
push [edi+10h] ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov [edi+4Ch],eax ;保存GetMessageA函数地址
call PushStr7 ;将下面的数据地址入栈
db "DispatchMessageA",0 ;参数2:要获取的函数名
PushStr7:
push [edi+10h] ;参数1:user32.dll模块基址
call esi ;GetProcAddress
mov [edi+50h],eax ;保存DispatchMessageA函数地址
MsgLoop:
call GetGlobal
mov edi,eax
push 0
push 0
push 0
lea edx,[edi+54h]
push edx
call dword ptr[edi+4Ch]
lea edx,[edi+54h]
push edx
call dword ptr[edi+50h]
jmp MsgLoop
;----------------------------------------------------
pop ebp
ret
WndProc:
push ebp
mov ebp,esp
call GetGlobal
mov edi,eax
;------------------------------------------
push [ebp+14h]
push [ebp+10h]
push [ebp+0Ch]
push [ebp+08h]
call dword ptr[edi+44h]
;------------------------------------------
pop ebp
ret 10h
CreateControl:
call GetGlobal
mov edi,eax
push 0 ;lpParam
push [edi] ;hInstance
push 1 ;hMenu
push [edi+64h] ;hWndParent
push 20 ;nHeight
push 100 ;nWidth
push 0 ;Y
push 0 ;X
push 50800000h ;dwStyle
push 0 ;lpWindowName
call PushStr10
db "Edit",0 ;lpClassName
PushStr10:
push 0 ;dwExStyle
call dword ptr[edi+48h] ;CreateWindowExA
ret
GetGlobal:
mov eax,[esp]
and eax,0FFFFF000h
add eax,400h
ret
end main