首页
社区
课程
招聘
[求助]在win7下kernel32.dll地址获取正确,通过kernel32的地址查找的LoadLibraryA也对了,怎么GetProcAddress地址获取不对啊?
发表于: 2011-5-26 23:34 10815

[求助]在win7下kernel32.dll地址获取正确,通过kernel32的地址查找的LoadLibraryA也对了,怎么GetProcAddress地址获取不对啊?

2011-5-26 23:34
10815
【求助】在win7下kernel32.dll地址获取正确,通过kernel32的地址查找的LoadLibraryA也对了,怎么GetProcAddress地址获取不对啊?
程序基本上就是是把网上找的取api地址的方法,和在win7下取kernel32.dll地址的方法放到一起组成的。

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

__inline __declspec(naked) unsigned int findkerneldll(){
        __asm{
    push esi
        push edi
        push ecx
    xor ecx, ecx
    mov esi, fs:0x30
    mov esi, [esi + 0x0c]
    mov esi, [esi + 0x1c]
next_module:
    mov eax, [esi + 0x8]
    mov edi,[esi+0x20]
    mov esi ,[esi]
    cmp [edi+12*2],cx
    jne next_module
        pop ecx
        pop edi
    pop esi
    Ret
        }
}
unsigned int GetFunctionByName(unsigned int ImageBase,const char*FuncName,int flen)
{
        unsigned int FunNameArray,PE,Count=0,*IED;
        __asm
        {
                mov eax,ImageBase
                        add eax,0x3c//指向PE头部偏移值e_lfanew
                        mov eax,[eax]//取得e_lfanew值
                        add eax,ImageBase//指向PE header
                        //cmp [eax],0x00004550
                        //jne NotFound//如果ImageBase句柄有错
                        mov PE,eax
                        mov eax,[eax+0x78]
                        add eax,ImageBase
                        mov [IED],eax//指向IMAGE_EXPORT_DIRECTORY

                        mov eax,[eax+0x20]
                        add eax,ImageBase
                        mov FunNameArray,eax//保存函数名称指针数组的指针值
                        mov ecx,[IED]
                        mov ecx,[ecx+0x14]//根据引出函数个数NumberOfFunctions设置最大查找次数
FindLoop:
                push ecx//使用一个小技巧,使用程序循环更简单
                        mov eax,[eax]
                        add eax,ImageBase
                        mov esi,FuncName
                        mov edi,eax
                        mov ecx,flen//逐个字符比较,如果相同则为找到函数,注意这里的ecx值
                        cld
                        rep cmpsb
                        jne FindNext//如果当前函数不是指定的函数则查找下一个
                        add esp,4//如果查找成功,则清除用于控制外层循环而压入的Ecx,准备返回
                        mov eax,[IED]
                        mov eax,[eax+0x1c]
                        add eax,ImageBase//获得函数地址表
                        shl Count,2//根据函数索引计算函数地址指针=函数地址表基址+(函数索引*4)
                        add eax,Count
                        mov eax,[eax]//获得函数地址相对偏移量
                        add eax,ImageBase//计算函数真实地址,并通过Eax返回给调用者
                        jmp Found
FindNext:
                inc Count//记录函数索引
                        add [FunNameArray],4//下一个函数名指针
                        mov eax,FunNameArray
                        pop ecx//恢复压入的ecx(NumberOfFunctions),进行计数循环
                        loop FindLoop//如果ecx不为0则递减并回到FindLoop,往后查找
NotFound:xor eax,eax//如果没有找到,则返回0
Found: nop
        }
}

typedef HMODULE (WINAPI *fun_ptr)(LPCSTR);
int main()
{

        unsigned int keradd;
        unsigned int loadlibfun,getprofun;
        HANDLE lh,mytest;
        fun_ptr pmytestfun;

        unsigned int test;
        char title[]="test",user32[]="user32.dll",msgf[]="MessageBoxA";

        lh = LoadLibraryA("kernel32.dll");
        printf("real--kernel32.dll--:%x\n",lh);
        printf("real\"LoadLibraryA\" :%x\n",(unsigned int)LoadLibraryA);
        printf("real\"GetProcAddress\" :%x\n",(unsigned int)GetProcAddress);

        lh = LoadLibraryA("user32.dll");
        printf("real--user32.dll--:%x\n",lh);
        test = (unsigned int)GetProcAddress(lh,"MessageBoxA");
        printf("real\"MessageBoxA\":%x\n\n",(unsigned int)MessageBoxA);

        keradd = findkerneldll();
        printf("my kernel32.dll:%x\n",keradd);

       
        getprofun=GetFunctionByName(keradd,"GetProcAddress",14);
        loadlibfun=GetFunctionByName(keradd,"LoadLibraryA",12);
       
       
        printf("my \"LoadLibraryA\":%x\n",loadlibfun);
        printf("my \"GetProcAddress\":%x\n",getprofun);
        pmytestfun=(fun_ptr)loadlibfun;
        mytest=pmytestfun("user32.dll");
        printf("my user32.dll:%x\n",(unsigned int)mytest );
        printf("my \"MessageBoxA\":%x\n",GetFunctionByName((unsigned int)mytest,"MessageBoxA",11));
       

//         __asm
//         {
//                 lea eax,user32
//                         push eax
//                         call dword ptr loadlibfun //相当于执行LoadLibrary("user32");
//                         lea ebx,msgf
//                         push 0x0b//"MessageBoxA"的长度
//                         push ebx
//                         push eax
//                         call GetFunctionByName
//                         mov ebx,eax
//                         add esp,0x0c//GetFunctionByName使用C调用约定,由调用者调整堆栈
//                         push 0
//                         lea eax,title
//                         push eax
//                         push eax
//                         push 0
//                         call ebx//相当于执行MessageBox(NULL,"test","test",MB_OK)
//         }

        return 0;
}


[峰会]看雪.第八届安全开发者峰会10月23日上海龙之梦大酒店举办!

上传的附件:
  • 1.png (62.74kb,226次下载)
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 3800
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Win7啊,建议你用OD看一下,之后你就明白了
2011-5-27 01:04
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
WIN7的基址是变的...
2011-6-14 22:18
0
游客
登录 | 注册 方可回帖
返回
//