注册 登录
编程论坛 汇编论坛

【原创】masm无jmp table直接调用API示范教程(简单有效 附转换工具下载)

zklhp 发布于 2012-02-08 15:24, 845 次点击
;*****************************************************************************************************************
;作者:zklhp
;Email:zklhp@
;QQ:493165744
;*****************************************************************************************************************

问题的来源来自这个贴 http://www.

核心就是 C语言调用API的时候没有jmp table 而用masm调用时会生成jmp table

jmp table的相关知识可以看罗云彬的书中PE文件部分 这里不多说

上代码

程序代码:


;MASMPlus 代码模板 - 控制台程序
;
*****************************************************************************************************************
;
作者:zklhp
;
Email:zklhp@
;
QQ:493165744
;
直接调用API示范教程
;
*****************************************************************************************************************
.386
.model flat, stdcall
option casemap :none

include windows.inc    ;或者包含工具包中提供的argcount.asm 两者原理一样
;
include user32.inc
;
include kernel32.inc
;
include masm32.inc
;
include gdi32.inc
include user32d.inc
include kernel32d.inc

;includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
;includelib masm32.lib
include macro.asm

.data
    lpMsg        db "Hello World!",0
   
.data?
    buffer    db 260 dup(?)
   
.CODE
START:
   
    MessageBox 0,offset lpMsg,CTXT('直接调用哦'),0
    ;暂停显示,回车键关闭
    ExitProcess 0
   
end START



反汇编

程序代码:


00401000 >  6A 00           PUSH 0
00401002    68 0D304000     PUSH CONSOLE.0040300D
00401007    68 00304000     PUSH CONSOLE.00403000                    ; ASCII "Hello World!"
0040100C    6A 00           PUSH 0
0040100E    FF15 08204000   CALL DWORD PTR DS:[<&user32.MessageBoxA>>; user32.MessageBoxA
00401014    6A 00           PUSH 0
00401016    FF15 00204000   CALL DWORD PTR DS:[<&kernel32.ExitProces>; kernel32.ExitProcess



奥秘在工具生成的user32d.inc文件中

程序代码:


externdef _imp__MessageBoxA@16:PTR pr4
MessageBox equ <invoke _imp__MessageBoxA@16,>


实现机制 Hume 大大的文章中提到过 可惜的是10年后我才看到 唉~

iWin32,iWin32i,避免jmp tabel,有两种方法避免生成jmp tabel(thx to EliCZ's macro)

    一种我以前写的一篇文章里面介绍过,就是利用声明

    _imp__&Win32Api&A proto :DWORD,....
    然后
    call dword ptr [_imp__&Win32Api&A]

    格式另一种是ELiCZ的方法,就是声明
    externdef _imp__&Win32Api&A@NUM:DWORD,其中NUM是参数个数
    然后
    call _imp__&Win32Api&A来调用.

    由于用EliCZ的方法写的macro较长,下面根据我的方法写一个宏:

    iWin32    Macro    Win32API:REQ,args:VARARG
        LOCAL    sz1
    sz1    TEXTEQU <>
%    FOR pxx,
       IFNB

         push pxx
         sz1  CATSTR sz1,<,:DWORD>
       ENDIF
    ENDM
    sz1 SUBSTR sz1,2,@SizeStr(%sz1)-1
    sz1    CATSTR <_imp__&Win32API>,<  PROTO  >,sz1
    sz1
    call    DWORD PTR [_imp__&Win32API]
        ENDM


下面iWin32i可以根据情况生成对ansi或者UNICODE的调用,前提是定义UNICODE=0或者TRUE...

        iWin32i    Macro    Win32API:REQ,args:VARARG
    IF        UNICODE
       iWin32    Win32API&W,
    ELSE
       iWin32    Win32API&A,
    ENDIF
        ENDM

根据原理其实有好多种不同的写法 工具生成的是externdef的 其实还可以这样

程序代码:


__imp__MessageBoxA@16 proto syscall
__imp__ExitProcess@4 proto syscall
;syscall调用规范不修饰

;调用
    xor eax,eax
    lea ecx,lpMsg
    mov edi,DWORD PTR [__imp__MessageBoxA@16]
    push eax
    push ecx
    push ecx
    push eax
    call edi
   
    push eax
    call DWORD PTR [__imp__ExitProcess@4]




程序代码:


_imp__MessageBoxA proto stdcall :DWORD,:DWORD,:DWORD,:DWORD
_imp__ExitProcess proto stdcall :DWORD

    ;切记第二种方法前面只有一个下划线 原因去查stdcall的修饰方式
    xor eax,eax
    lea ecx,lpMsg
    mov edi,DWORD PTR [_imp__MessageBoxA]
    push eax
    push ecx
    push ecx
    push eax
    call edi
   
    push eax
    call DWORD PTR [_imp__ExitProcess]




因为能用masm32工具包中的l2extia.exe转换所有写了这个例子 要是都手工生成就挺麻烦的 呵呵

从这个小例子也反映了汇编的灵活性 当然也反映了汇编的复杂性 在这里灵活的同义词就是复杂

代码+MasmPlus工程+转换软件
只有本站会员才能查看附件,请 登录



[ 本帖最后由 zklhp 于 2012-2-8 15:43 编辑 ]
5 回复
#2
zklhp2012-02-08 15:29
先自己顶一下下
#3
红色枫叶2012-11-08 19:47
弱弱的问句 为什么 我 把INc 拉到 l2extia.exe  没新的东西出来
#4
zklhp2012-11-08 19:53
以下是引用红色枫叶在2012-11-8 19:47:59的发言:

弱弱的问句 为什么 我 把INc 拉到 l2extia.exe  没新的东西出来
这么多年了 我也忘了。。
#5
红色枫叶2012-11-14 18:17
回复 4楼 zklhp
我表示我犯2了 应该是把LIB 而不是INC = =   
#6
zklhp2012-11-14 18:26
以下是引用红色枫叶在2012-11-14 18:17:50的发言:

我表示我犯2了 应该是把LIB 而不是INC = =   

能用了就好 祝玩的愉快
1