+ -
当前位置:首页 → 问答吧 → 【内联汇编】如何通过地址来调用某函数

【内联汇编】如何通过地址来调用某函数

时间:2010-12-19

来源:互联网

Assembly code

__asm 
    {
        mov eax, fs:[0x30]                ;point to PEB
        mov eax, [eax + 0x0C]                    ;point to _PEB_LDR_DATA 
        mov eax, [eax + 0x0C]                    ;point to InLoadOrderModuleList  
        mov eax, [eax]                    ;InLoadOrderLinks of this process 
        mov eax, [eax]                    ;InLoadOrderLinks of ntdll address
        mov eax, [eax + 0x18]                    ;DllBase  of kernel32 address
        mov edi,eax                    ;edi poin to kernel32

        //mov ebp,esp;
        //sub esp,100;       
        mov eax,[edi+3ch]                ;edx point to pe header
        mov edx,[edi+eax+78h]                    ;edx point to RVA of export table
        add edx,edi                    ;edx point to  VA of export table
        mov ecx,[edx+18h]        ;ecx point to the number of functions of export name table
        mov ebx,[edx+20h]                ;ebx point to RVA of export name table
        add ebx,edi                    ;ebx point to  VA of export name table

search:
        dec ecx                        ;loop counter ecx minusitself                        
        mov esi,[ebx+ecx*4]                ;esi get RVA of function name from last
        add esi, edi;                    ;esi get VA of it
        mov eax,0x50746547                ;eax get PteG("GetP") 
        cmp [esi],eax                    ;compare [esi] with current block
        jne search
        mov eax,0x41636f72                ;eax get Acor("rocA")
        cmp [esi+4],eax                    ;compare second half
        jne search        
        mov ebx,[edx+24h]                ;ebx point to RVA of export index table                
        add ebx,edi                    ;ebx point to  VA of export index table    
        mov cx,[ebx+ecx*2]                ;
        mov ebx,[edx+1ch]                ;ebx point to RVA of export address table
        add ebx,edi                    ;ebx point to  VA of export address table
        mov eax,[ebx+ecx*4]                ;eax point to RVA of function
        add eax,edi                    ;eax point to  VA of function
        mov [ebp+76],eax                ;restore somewhere

call GetProAddress:        
        push 0;
        push DWORD PTR 0x57656C            ; leW(" leA") 
        push DWORD PTR 0x69466574        ;iFet("teFi")
        push DWORD PTR 0x61657243        ;aerC("Crea")
        push esp
        push edi
        call [ebp+76]
        mov  [ebp+80],eax                

call CreateFileA:
        push        0    
        push        0    
        push        2    
        push        0    
        push        0    
        push        40000000h  
        push  offset string "C:\\test\\test.txt"        
               call [ebp+80];




    }



上面是网上的代码加上自己一点点修改,目的是先找到kernel32,然后在找到getProcAdress,然后拿到CreateFileA地址,然后调用它,前面的步骤都得到正确结果了,
1 但是调用的call CreateFileA:部分出问题了,那个函数原型例子是
CreateFileA("c:\\test\\test.txt",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,NULL,NULL);不知道是不是这么调用
,其实callGetProAddress我也不明白,参数应该就只有kernel32地址和函数名,为什么要push 0;(用来截断字符?)和push esp

2序数表我调试的结果是序数表是从2开始计数的,不知道自己有没有调错,下面是某此调试的结果,75a87848 是我查到的序数表地址,如果这样计数序数,那么再查地址表的时候岂不是多了,还是说地址表也刚好差2,还有存序数为什么用cx不用ecx
75a87848 02 00 03 00 04 00 05 00-06 00 07 00 08 00 09 00 ................
75a87858 0a 00 0b 00 0c 00 0d 00-0e 00 0f 00 10 00 11 00 ................
75a87868 12 00 13 00 14 00 15 00-16 00 17 00 18 00 19 00 ................
75a87878 1a 00 1b 00 1c 00 1d 00-1e 00 1f 00 20 00 21 00 ............ .!.
75a87888 22 00 23 00 24 00 25 00-26 00 27 00 28 00 29 00 ".#.$.%.&.'.(.).
75a87898 2a 00 2b 00 00 00 2c 00-2d 00 2e 00 2f 00 30 00 *.+...,.-.../.0.
75a878a8 31 00 32 00 33 00 34 00-35 00 36 00 37 00 38 00 1.2.3.4.5.6.7.8.
75a878b8 39 00 3a 00 3b 00 3c 00-3d 00 3e 00 3f 00 40 00 9.:.;.<.=.>.?.@.

作者: aquastar   发布时间: 2010-12-19

色播病毒 FakeQVod 里用的好些就是这个代码?
1. 函数调用各个参数的说明,可以参考 msdn 的,比较详细,甚至还有例子。那个 push 0 是表明作为函数名的字符串的结束的。
2. 序号表这块,确实有些乱!详细说明可以参考侯捷的那本“Windows 95 系统程式设计大奥秘”里“PE与COFF OBJ 档案格式”中输出节部分。

作者: zara   发布时间: 2010-12-20

1.push 0 是 表明做为函数名的字符串结束;push esp:esp是一个指向字符串“CreateFileA”的指针,实际上这个push esp才是函数GetProcAddress的参数之一,push edi:edi指向字符串“kernel32.dll”做为GetProcAddress的第二个参数,然后调用函数GetProcAddress找到函数CreateFileA,从eax返回,调用结束之后把返回值存入[ebp+80].
2.至于第二问,不是到是不是因为编码格式的问题,比如unicode编码方式是widechar,一个字符占用2个字节......

作者: hxp2k6   发布时间: 2010-12-20

引用 1 楼 zara 的回复:
色播病毒 FakeQVod 里用的好些就是这个代码?
1. 函数调用各个参数的说明,可以参考 msdn 的,比较详细,甚至还有例子。那个 push 0 是表明作为函数名的字符串的结束的。
2. 序号表这块,确实有些乱!详细说明可以参考侯捷的那本“Windows 95 系统程式设计大奥秘”里“PE与COFF OBJ 档案格式”中输出节部分。


msdn我查过,参数我确定,如下是在vs中反汇编调试的结果
Assembly code

CreateFileA("c:\\test\\test.txt",0x40000000L,0,0,2,0,0);
01101436  mov         esi,esp 
01101438  push        0    
0110143A  push        0    
0110143C  push        2    
0110143E  push        0    
01101440  push        0    
01101442  push        40000000h 
01101447  push        offset string "c:\\test\\test.txt" (110573Ch) 
0110144C  call        dword ptr [__imp__CreateFileA@28 (11081A4h)] 
01101452  cmp         esi,esp 
01101454  call        @ILT+315(__RTC_CheckEsp) (1101140h) 


CreateFileA("c:\\test\\test.txt",0x40000000L,0,0,2,0,0);是执行成功了的,参数都换成了实际的数值,都是常用设置就是创建一个文件,对应的反汇编的这一段
Assembly code

01101436  mov         esi,esp 
01101438  push        0    
0110143A  push        0    
0110143C  push        2    
0110143E  push        0    
01101440  push        0    
01101442  push        40000000h 
01101447  push        offset string "c:\\test\\test.txt" (110573Ch)


放到内联汇编中,貌似不能成功执行,为什么呢

作者: aquastar   发布时间: 2010-12-20

引用 2 楼 hxp2k6 的回复:
1.push 0 是 表明做为函数名的字符串结束;push esp:esp是一个指向字符串“CreateFileA”的指针,实际上这个push esp才是函数GetProcAddress的参数之一,push edi:edi指向字符串“kernel32.dll”做为GetProcAddress的第二个参数,然后调用函数GetProcAddress找到函数CreateFileA,从eax返回,调用结束……

我上面的内联汇编,如此push参数调用,
Assembly code

01101436  mov         esi,esp 
01101438  push        0    
0110143A  push        0    
0110143C  push        2    
0110143E  push        0    
01101440  push        0    
01101442  push        40000000h 
01101447  push        offset string "c:\\test\\test.txt" (110573Ch)


但是报 “第二操作数”中的内联汇编语法错误;找到“bad token” 不能这么压啊?

作者: aquastar   发布时间: 2010-12-20

创建文件不能成功,在调试软件里看看 LastError 是什么错误了。最可能的就是文件名不正确吧,比如路径 test 不存在,结束的 00 字节有吗,……

作者: zara   发布时间: 2010-12-20

由Windows版移至汇编语言版。

作者: chang_bo   发布时间: 2010-12-20

热门下载

更多