#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

void PopMessageBox()
{
    __asm
    {
            nop
nop
nop
nop
nop
nop
jmp start
find_function:
    //寻找kernel32.dll的基址
    mov eax,fs:[30h]
mov eax,[eax+0ch]
mov eax,[eax+14h]
module_loop:
    mov eax,[eax]
mov esi,[eax+28h]
cmp byte ptr [esi+0ch],'3'   //搜索kernel32.dll
jne module_loop

mov ebp,[eax+010h]    //ebx为kernel32.dll的基址

mov eax,[ebp+03ch]
mov ecx,[ebp+eax+78h]  //读取PE结构中的导出表地址
add ecx,ebp     //ecx定位到导出表

mov ebx,[ecx+20h]
add ebx,ebp     //ebx定位到导出名称指针表

xor edi,edi
pushad
name_loop:
   popad
mov esi,[ebx+edi*4]   //读取一个指向函数名的指针
add esi,ebp       //定位到函数名字符串
inc edi
mov edx,esp     //获取栈内要获取的函数名起始地址
add edx,4
pushad      //寄存器入栈
mov eax,edx
mov ebx,esi
name_cmp_loop:
    xor edx,edx
mov cl,byte ptr [ebx]
mov ch,byte ptr [eax]
cmp cl,ch
jne name_loop
inc ebx
inc eax
cmp cl,dl
jz break_name_loop
jmp name_cmp_loop
break_name_loop:
    popad
//找到函数名 
mov ebx,[ecx+24h]   //定位到导出序数表RVA
add ebx,ebp

mov di,[ebx+2*edi]
dec di
mov ebx,[ecx+1ch]   //定位到导出地址表RVA
add ebx,ebp
add ebp,[ebx+4*edi]    //读取函数地址
xchg eax,ebp

ret
start:
   //LoadLibraryA
   push 0x00
push 0x41797261
push 0x7262694C
            push 0x64616F4C
call find_function
push eax     //将找到的函数地址入栈

   //GetProcAddress
push 0x00007373
push 0x65726464
push 0x41636F72
push 0x50746547
call find_function
push eax

push 0x00003233                        //32
push 0x72657375                    //user
push esp                           //lpFileName

mov eax,[esp+32]
call eax                        //call LoadLibraryA,返回值存放在eax中
mov edi,eax                     //edi存放user32.dll句柄

mov ebx,dword ptr [esp+8]       //获取GetProcAddress函数地址

push 0x0041786f                    //oxA
push 0x42656761                    //ageB
            push 0x7373654d                    //Mess
push esp
push edi
call ebx       //返回值保存在eax中

push 0
push 0
push 0
push 0
call eax

push 0x00737365
push 0x636F7250
push 0x74697845
call find_function

push 0
call eax
nop
nop
nop
nop
nop
    }
}

int main()
{
    PopMessageBox();
    return 0;
}