首页
社区
课程
招聘
win32汇编求解
发表于: 2009-12-19 00:59 4035

win32汇编求解

2009-12-19 00:59
4035
_GetApi        proc        _hModule,_lpszApi
        LOCAL        @dwReturn,@dwStringLength
       
        pushad
        mov        @dwReturn,0
;*************************************************
;重定位
;*************************************************
        call        @F
        @@:
        pop        ebx
        sub        ebx,offset @B
;*************************************************
;创建用于错误处理的SEH结构
;*************************************************
        assume        fs:nothing
        push        ebp
        lea        eax,[ebx+offset _Error]
        push        eax
        lea        eax,[ebx+offset        _SEHHandler]
        push        eax
        push        fs:[0]
        mov        fs:[0],esp
;**************************************************
;计算API字符串的长度(带尾部的0)
;**************************************************
        mov        edi,_lpszApi
        mov        ecx,-1
        xor        al,al
        cld
        repnz        scasb
        mov        ecx,edi
        sub        ecx,_lpszApi
        mov        @dwStringLength,ecx
;****************************************************
;从PE文件头的数据目录获取导出表地址
;****************************************************
        mov        esi,_hModule
        add        esi,[esi+3ch]
        assume        esi:ptr IMAGE_NT_HEADERS
        mov        esi,[esi].OptionalHeader.DataDirectory.VirtualAddress
        add        esi,_hModule
        assume        esi:ptr IMAGE_EXPORT_DIRECTORY
;*****************************************************
;查找符合名称的导出函数名
;*****************************************************
        mov        ebx,[esi].AddressOfNames
        add        ebx,_hModule
        xor        edx,edx
        .repeat
                push        esi
                mov        edi,[ebx]
                add        edi,_hModule
                mov        esi,_lpszApi
                mov        ecx,@dwStringLength
                repz        cmpsb
                .if        ZERO?
                        pop        esi
                        jmp        @F
                .endif       
                pop        esi
                add        ebx,4
                inc        edx
        .until        edx >= [esi].NumberOfNames
        jmp        _Error
@@:
;*******************************************************
;API名称索引--》序号索引--》地址索引
;*******************************************************
        sub        ebx,[esi].AddressOfNames
        sub        ebx,_hModule       
        shr        ebx,1
        add        ebx,[esi].AddressOfNameOrdinals
        add        ebx,_hModule
        movzx        eax,word ptr [ebx]
        shl        eax,2
        add        eax,[esi].AddressOfFunctions
        add        eax,_hModule
;*********************************************************
;从地址表得到到处地址
;*********************************************************
        mov        eax,[eax]
        add        eax,_hModule
        mov        @dwReturn,eax
_Error:
        pop        fs:[0]
        add        esp,0ch
        assume        esi:nothing
        popad
        mov        eax,@dwReturn
        ret
_GetApi        endp

罗云彬win32汇编的例子
;API名称索引--》序号索引--》地址索引
        sub        ebx,[esi].AddressOfNames
        sub        ebx,_hModule       
        shr        ebx,1
        add        ebx,[esi].AddressOfNameOrdinals
        add        ebx,_hModule
        movzx        eax,word ptr [ebx]
        shl        eax,2
        add        eax,[esi].AddressOfFunctions
        add        eax,_hModule

开头为何SUB 看不大懂 所以整段如何实现注释里的功能不大明白

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
代码没贴全吧。@B和@F的位置找不到。offset @B应该为6。你再发下代码。我夜晚回来,不能帮你看了。闪了。
2009-12-19 11:26
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
3
mov  ebx,[esi].AddressOfNames
  add  ebx,_hModule
以上两行后,ebx指向AddressOfNames数组的开头
然后就是循环取ebx指向的地址所保存的DWORD值,为函数名字符串偏移,加上基址得到函数名字符串地址,使用rep cmpsb与所需的函数名进行比对,如果两者符合(.if  ZERO?)就跳到你所指出的位置:

sub  ebx,[esi].AddressOfNames
跳到这里时ebx指向AddressOfNames数组中满足要求的那一项。
因此sub [esi].AddressOfNames再sub _hModule后,得到的ebx就是它在AddressOfNames数组中的相对偏移(可以看到这两句实际上是与前面我写出的那两句是对应的)
得到这个相对偏移,是为了得到在AddressOfNames数组中的相对序号,以便根据这个序号,在AddressOfNameOrdinals数组中查找以函数导出序号排列时的真正序号。由于AddressOfNames数组是个DWORD的数组,每个元素有4字节,而AddressOfNameOrdinals数组是个word的数组,每个数组有两字节,因此,此时ebx只需要除以4,就是在AddressOfNames数组中的序号,再乘以2则得到在AddressOfNameOrdinals数组中的偏移,因此两步合成一步,就只需除以2,即为shr ebx, 1。
之后就根据这个相对偏移,在AddressOfNameOrdinals数组中找到以函数序号排列时的真正序号,然后从AddressOfFunctions数组里找到函数地址偏移,加上基址得到函数地址。
流程就是这样的。如果不明白,仔细阅读有关PE文件头结构特别是导出表方面的知识。
2009-12-19 19:16
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
因此sub [esi].AddressOfNames再sub _hModule后,得到的ebx就是它在AddressOfNames数组中的相对偏移(可以看到这两句实际上是与前面我写出的那两句是对应的)
得到这个相对偏移,是为了得到在AddressOfNames数组中的相对序号,以便根据这个序号,在AddressOfNameOrdinals数组中查找以函数导出序号排列时的真正序号。由于AddressOfNames数组是个DWORD的数组,每个元素有4字节,而AddressOfNameOrdinals数组是个word的数组,每个数组有两字节,因此,此时ebx只需要除以4,就是在AddressOfNames数组中的序号,再乘以2则得到在AddressOfNameOrdinals数组中的偏移,因此两步合成一步,就只需除以2,即为shr ebx, 1。

正是需要的答案 非常感谢。
顺便也感谢下楼上楼上的朋友
2009-12-19 20:03
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
小聪果然强大。输出表没仔细看过过,原来也有不少东西,明天好好看看书,学习了。
2009-12-19 20:10
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看不懂
2009-12-21 12:15
0
雪    币: 808
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
楼主是指这段吧

call  @F
  @@:
  pop  ebx
  sub  ebx,offset @B

罗云彬不是讲的很清楚了吗?多看几遍就知道了。
2009-12-21 18:12
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
结了的帖子本来不说啥了
但是这位朋友麻烦把帖子认真看看
进个帖子就说类似 “你不懂C语言吧 买本谭浩强吧”
这是不是太胡闹搞笑了
2009-12-22 14:42
0
雪    币: 808
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
晕,算我白说了。
2009-12-22 19:28
0
游客
登录 | 注册 方可回帖
返回
//