【问题标题】:How can I know what this does?我怎么知道这是做什么的?
【发布时间】:2010-03-11 22:38:56
【问题描述】:

我从某个软件中提取了这段汇编代码,但不幸的是,我对汇编器一无所知,而我接触到的汇编器部分又回到了 Commodore Amiga 的 68000 中。

谁能指导我如何理解这段代码,而无需从头开始学习汇编程序,或者告诉我它的作用?

是否有任何类型的“模拟器”可供我运行它以查看它的作用?

   -[ObjSample Param1:andParam2:]:
    00000c79    pushl   %ebp
    00000c7a    movl    %esp,%ebp
    00000c7c    subl    $0x48,%esp
    00000c7f    movl    %ebx,0xf4(%ebp)
    00000c82    movl    %esi,0xf8(%ebp)
    00000c85    movl    %edi,0xfc(%ebp)
    00000c88    calll   0x00000c8d
    00000c8d    popl    %ebx
    00000c8e    cmpb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)
    00000c95    jel 0x00000d47
    00000c9b    movb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)
    00000ca2    movl    0x7dc0-0xc8d(%ebx),%eax
    00000ca8    movl    %eax,0x04(%esp)
    00000cac    movl    0x7df4-0xc8d(%ebx),%eax
    00000cb2    movl    %eax,(%esp)
    00000cb5    calll   _objc_msgSend
    00000cba    movl    0x7dbc-0xc8d(%ebx),%edx
    00000cc0    movl    %edx,0x04(%esp)
    00000cc4    movl    %eax,(%esp)
    00000cc7    calll   _objc_msgSend
    00000ccc    movl    %eax,0xe4(%ebp)
    00000ccf    movl    0x7db8-0xc8d(%ebx),%eax
    00000cd5    movl    %eax,0x04(%esp)
    00000cd9    movl    0xe4(%ebp),%eax
    00000cdc    movl    %eax,(%esp)
    00000cdf    calll   _objc_msgSend
    00000ce4    leal    (%eax,%eax),%edi
    00000ce7    movl    %edi,(%esp)
    00000cea    calll   _malloc
    00000cef    movl    %eax,%esi
    00000cf1    movl    %edi,0x08(%esp)
    00000cf5    movl    $-[ObjSample delegate],0x04(%esp)
    00000cfd    movl    %eax,(%esp)
    00000d00    calll   _memset
    00000d05    movl    $0x00000004,0x10(%esp)
    00000d0d    movl    %edi,0x0c(%esp)
    00000d11    movl    %esi,0x08(%esp)
    00000d15    movl    0x7db4-0xc8d(%ebx),%eax
    00000d1b    movl    %eax,0x04(%esp)
    00000d1f    movl    0xe4(%ebp),%eax
    00000d22    movl    %eax,(%esp)
    00000d25    calll   _objc_msgSend
    00000d2a    xorl    %edx,%edx
    00000d2c    movl    %edi,%eax
    00000d2e    shrl    $0x03,%eax
    00000d31    jmp 0x00000d34
    00000d33    incl    %edx
    00000d34    cmpl    %edx,%eax
    00000d36    ja  0x00000d33
    00000d38    movl    %esi,(%esp)
    00000d3b    calll   _free
    00000d40    movb    $0x01,_isAuthenticated-0xc8d(%ebx)
    00000d47    movzbl  _isAuthenticated-0xc8d(%ebx),%eax
    00000d4e    movl    0xf4(%ebp),%ebx
    00000d51    movl    0xf8(%ebp),%esi
    00000d54    movl    0xfc(%ebp),%edi
    00000d57    leave
    00000d58    ret

【问题讨论】:

  • 真正的问题是什么 - 你丢失了源代码还是什么?

标签: assembly disassembly


【解决方案1】:

这设置了一个栈帧,为局部变量分配了0x48字节并保存了ebx、esi和edi,这是一个非常标准的函数prolog。

00000c79    pushl   %ebp
00000c7a    movl    %esp,%ebp
00000c7c    subl    $0x48,%esp
00000c7f    movl    %ebx,0xf4(%ebp)
00000c82    movl    %esi,0xf8(%ebp)
00000c85    movl    %edi,0xfc(%ebp)

这是一个汇编程序技巧,用于将 ebx 设置为指向代码,完成后 ebx 包含 00000c8d。

00000c88    calll   0x00000c8d
00000c8d    popl    %ebx

这个位确保函数只运行一次,如果你第二次调用它 跳到最后(jel 0x00000d47)

00000c8e    cmpb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)
00000c95    jel 0x00000d47
00000c9b    movb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)

该位将相对于 ebx 的值复制到本地(堆栈)变量空间,请记住 ebx 指向当前函数,但与 ebx 的偏移量很大。这很可能是嵌入在代码中的常量数据,它们被设置为调用函数的参数。

00000ca2    movl    0x7dc0-0xc8d(%ebx),%eax
00000ca8    movl    %eax,0x04(%esp)
00000cac    movl    0x7df4-0xc8d(%ebx),%eax
00000cb2    movl    %eax,(%esp)

调用函数。

00000cb5    calll   _objc_msgSend

更多的常量值压入栈中并再次调用同一个函数,这次函数调用的返回值被保存到一个局部变量:0xe4(%ebp)

00000cba    movl    0x7dbc-0xc8d(%ebx),%edx
00000cc0    movl    %edx,0x04(%esp)
00000cc4    movl    %eax,(%esp)
00000cc7    calll   _objc_msgSend
00000ccc    movl    %eax,0xe4(%ebp)

为函数调用压入堆栈的更多值,这次一个值是相对于 ebx 的常量,另一个值是上一次调用的返回值。

00000ccf    movl    0x7db8-0xc8d(%ebx),%eax
00000cd5    movl    %eax,0x04(%esp)
00000cd9    movl    0xe4(%ebp),%eax
00000cdc    movl    %eax,(%esp)
00000cdf    calll   _objc_msgSend

从该调用中获取返回值,将其加倍并分配那么多内存。

00000ce4    leal    (%eax,%eax),%edi
00000ce7    movl    %edi,(%esp)
00000cea    calll   _malloc

用在 [ObjSample delegate] 中找到的字节填充内存

00000cef    movl    %eax,%esi
00000cf1    movl    %edi,0x08(%esp)
00000cf5    movl    $-[ObjSample delegate],0x04(%esp)
00000cfd    movl    %eax,(%esp)
00000d00    calll   _memset

发送另一条消息,这条带参数:0xe4(%ebp),来自 ebx 的常量,mallocd ptr,malloc 大小,4。大概这会在我们的 malloc 缓冲区中发送消息, (缓冲区稍后被释放而不是返回给调用者)

00000d05    movl    $0x00000004,0x10(%esp)
00000d0d    movl    %edi,0x0c(%esp)
00000d11    movl    %esi,0x08(%esp)
00000d15    movl    0x7db4-0xc8d(%ebx),%eax
00000d1b    movl    %eax,0x04(%esp)
00000d1f    movl    0xe4(%ebp),%eax
00000d22    movl    %eax,(%esp)
00000d25    calll   _objc_msgSend

清除 edx 并将 sendmessage 调用的返回值保存到 edi。

00000d2a    xorl    %edx,%edx
00000d2c    movl    %edi,%eax

eax >> 3,然后是while (edx < eax) ++edx;,这没有多大意义。

00000d2e    shrl    $0x03,%eax
00000d31    jmp 0x00000d34
00000d33    incl    %edx
00000d34    cmpl    %edx,%eax
00000d36    ja  0x00000d33

释放 mallocd 内存

00000d38    movl    %esi,(%esp)
00000d3b    calll   _free

将 _isAuthenticated 设置为 true,同时将返回值设置为 true。这个变量出现 在代码中,或者可能是全局的。

00000d40    movb    $0x01,_isAuthenticated-0xc8d(%ebx)
00000d47    movzbl  _isAuthenticated-0xc8d(%ebx),%eax

恢复寄存器并返回。

00000d4e    movl    0xf4(%ebp),%ebx
00000d51    movl    0xf8(%ebp),%esi
00000d54    movl    0xfc(%ebp),%edi
00000d57    leave
00000d58    ret

【讨论】:

    【解决方案2】:

    艰巨的工作...您的汇编程序只是一个例程,但它引用其他子例程和全局或静态变量,所以我们能做的最好的事情就是用一种更易读的语言来了解它的等价物。但是……让我们试试吧! (类 C 语言)

    int unknown_function(/* Parameters? */)
    {
    static char bDoOnce;
    static char isAuthenticated;
    uint32 tmp1,tmp2,tmp3;
    void *p;
    int i;
    
           if (bDoOnce == ObjSample_delegate) {
                 return isAuthenticated;
           }
           bDoOnce = ObjSample_delegate;
           tmp1= objc_msgSend(some_data1, some_data2);
           tmp2 = objc_msgSend(tmp1, some_data3);
           tmp3 = objc_msgSend(tmp2, some_data4);
           p = malloc(tmp3*2);
           memset(p, ObjSample_delegate, tmp3*2);
           objc_msgSend(tmp2,some_data5,p, tmp3*2,4);
           for (i = 0; i < tmp3/4; ++i) {
           }
           free(p);
           isAuthenticated = 1;
           return isAuthenticated;
    }
    

    嗯...没有足够的信息来弄清楚到底发生了什么(并不是说我可能做错了什么;)) 该程序包含太多“some_data”,并且这里的空for循环似乎只是为了消耗CPU。嗯……是gnu ObjectiveC编译的函数吗?

    对不起,我试过了,但我不能说更有用。无论如何,我希望它可以帮助你。 问候

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多