首页
社区
课程
招聘
[旧帖] [原创]用汇编构造sprintf函数 0.00雪花
发表于: 2012-8-24 18:03 3766

[旧帖] [原创]用汇编构造sprintf函数 0.00雪花

2012-8-24 18:03
3766

使用汇编构造sprintf函数。
我没有去逆向sprintf函数,主要是过程太多了,并且只要知道运算结果就能大概推算出过程了。
以下构造并不完整,但能实现sprintf函数大多数功能,比如字符串中的'%%'解析为'%','%x'解析为十六进制单字节数,'%X'解析为十六进制双字数,'%d'解析为十进制数,其他的出于时间关系,我就没写了。
另外,为了方便调用,我将过程写为__stdcall调用方式,也算是__stdcall的sprintf吧。。。
在使用前应该加上两个宏:

put macro
    mov     byte ptr [ebp+ecx+08h], al
endm

get macro
    mov     al, byte ptr [ebp+ebx+0ch]
endm

put就是向新指针写入一字节,get就是向老字符串读取一字节

目前暂时只能处理ANSI格式字符串,不过对于不熟悉Unicode的童鞋们也够了

废话不多说,上源码:

;void sprintf(LPCTSTR lpFormatStr, LPCSTR lpStr, ...)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sprintf:
    push    ebp
    mov     ebp, esp
    ;无局部变量
    xor     ebx, ebx                              ;格式化前指针
    xor     ecx, ecx                              ;格式化后指针
    mov     edx, 0ch                              ;参数指针
@@1:                                              ;主循环
    inc     ecx
    get
    cmp     al, 0
    jz      @@end
    .if     al == '%'
        inc     ebx
        add     edx, 04h
        get
        .if     al == 'x'
            mov     al, '0'
            put

            inc     ecx
            mov     al, 'x'
            put

            xor     eax, eax
            mov     al, byte ptr [ebp+edx]
            ror     eax, 4

            .if     al > 9
                add     al, 37h
            .else
                add     al, 30h
            .endif
            inc     ecx
            put

            rol     eax, 4

            .if     al > 9
                add     al, 37h
            .else
                add     al, 30h
            .endif
            inc     ecx
            put

        .elseif al == 'X'
            mov     al, '0'
            put

            inc     ecx
            mov     al, 'x'
            put

            mov     eax, dword ptr [ebp+edx]
            push    edx

            mov     edx, 8
            .while  edx > 0

                push    eax
                dec     edx

                lea     edx, [edx*4]
                ror     eax, edx
                and     al, 0fh

                .if     al > 9
                    add     al, 37h
                .else
                    add     al, 30h
                .endif
                inc     ecx
                put

                pop     eax
            .endw
            pop     edx

        .elseif al == 'd'
            mov     eax, dword ptr [ebp+edx]

            push    ebx
            push    edx
            xor     ebx, ebx

            .while  eax > 0
                mov     edx, 0ah
                div     edx
                push    edx
                inc     ebx
            .endw

            .while ebx > 0
                pop     eax
                inc     ecx
                put
                dec     ebx
            .endw

            pop     edx
            pop     ebx

        .elseif al == '%'
            sub     edx, 04h
            put
        .endif

    .else
        put
    .endif

    inc     ebx
    jmp     @@1

@@end:                                              ;循环结束
    inc     ecx
    xor     al, al
    put

    leave
    sub     edx, 04h
    sub     esp, edx
    ret


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 185
活跃值: (70)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
同样的,也可以据此创建__stdcall调用协定的变长函数,首先创建一个函数过程:

std_sprintf proc lpFormatStr, lpStr

    ;函数过程前面自动生成push ebp/mov ebp, esp

    ;sprintf过程前面去掉这句

    jmp sprintf

    ret;这句要不要就无所谓了,不过有时没有这句编译不会通过

std_sprintf

现在就可以通过__stdcall调用变长函数了
2012-8-26 08:15
0
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
COOL。。。。。
2012-8-26 09:36
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
敢不敢再无聊点,敢不敢不用伪指令
2012-8-26 16:23
0
雪    币: 185
活跃值: (70)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
不是这个,如果直接构造这个函数就不能变长了,所以先自己构造一个函数头,在最后恢复堆栈
2012-8-26 19:20
0
雪    币: 78
活跃值: (85)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
楼主的精力真是好啊。。。。。
2012-8-26 21:14
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
貌似不错,学习了
2012-8-27 09:30
0
雪    币: 185
活跃值: (70)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
这个不是不错,,在我看来主要是现在高级语言流行,底层汇编用的越来越少,有一些功能没有用到,比如这个,__stdcall调用变长函数,看起来强大,是因为这方面的帖子少,并且这种技术对于现在已经没有多少实用价值了
2012-8-27 16:57
0
游客
登录 | 注册 方可回帖
返回
//