我正在尝试反汇编一个应用程序(从一家中国公司用英语构建)。

我找到了想要的文本字符串:

.data:0041048C aEraseError     db 'Erase error !',0Ah,0 ; DATA XREF:
.rdata:0040C624o
.data:0041048C                                         ; .rdata:0040CF28o ...


但是,我无法在代码中的任何位置找到它。奇怪的是,找到了一些文本字符串,但没有找到。

仅供参考:该应用程序还加载了一个自定义的.dll文件。文本位于主exe文件的.rdata段中,但我只是在代码中看不到它。我曾尝试过与其他反汇编程序配合使用,但我正在使用IDA。

#1 楼

您的字符串似乎具有0040C624的外部参照(交叉引用,请参见下文)。该字符串可能只是错误字符串数组中的一个条目,该数组本身开始于0040C624之前。您的原始源代码可能看起来像这样:

char *unused="unused string";
char *errors[] = {
    "error 0",
    "some other error",
    "yet another error",
    "Erase error!",
    "....",
};

void print_error_message(int index) {
    puts(errors[index]);
}

int handle_erase_error() {
    print_error_message(3);
}


如果您对此进行编译(我在Linux上使用gnu C,gcc -m32 xref.c)并将目标代码加载到IDA中,变成(省略了不相关的部分):

.text:08000000 print_error_message proc near           ; CODE XREF: handle_erase_error+Dp
.text:08000000                 push    ebp
.text:08000001                 mov     ebp, esp
.text:08000003                 sub     esp, 18h
.text:08000006                 mov     eax, [ebp+8]
.text:08000009                 mov     eax, errors[eax*4]
.text:08000010                 mov     [esp], eax      ; s
.text:08000013                 call    puts
.text:08000018                 leave
.text:08000019                 retn
.text:08000019 print_error_message endp


.data:08000030 unused          dd offset aUnusedString ; "unused string"
.data:08000034 errors          dd offset aError0       ; DATA XREF: print_error_message+9r
.data:08000034                                         ; "error 0"
.data:08000038                 dd offset aSomeOtherError ; "some other error"
.data:0800003C                 dd offset aYetAnotherErro ; "yet another error"
.data:08000040                 dd offset aEraseError   ; "Erase error!"
.data:08000044                 dd offset a____         ; "...."

.rodata:08000049 aUnusedString   db 'unused string',0    ; DATA XREF: .data:unusedo
.rodata:08000057 aError0         db 'error 0',0          ; DATA XREF: .data:errorso
.rodata:0800005F aSomeOtherError db 'some other error',0 ; DATA XREF: .data:08000038o
.rodata:08000070 aYetAnotherErro db 'yet another error',0 ; DATA XREF: .data:0800003Co
.rodata:08000082 aEraseError     db 'Erase error!',0     ; DATA XREF: .data:08000040o
.rodata:0800008F a____           db '....',0             ; DATA XREF: .data:08000044o


您会看到每个字符串在data部分中都有一个指针条目,在rodata中具有ascii数据(只读数据)部分。每个ascii字符串都有指向指向它的指针的外部参照(交叉引用)-这不是二进制文件的一部分;它不是二进制文件的一部分。 ida检测每个字符串在哪里被引用,并生成“反向引用”或外部参照。

重要的是:如果您只有一个,则可以使用它来查找字符串表(错误,在0x08000034处)。 ASCII字节。您可以从print_error_message函数查看字符串表的外部参照来查找字符串表本身的使用位置。相比之下,未使用的字符串没有外部参照,因为它没有在任何地方使用。

Ida将允许您双击外部参照以移动至“来自”外部的位置进行导航容易。

我将检查您是否有一个字符串数组,该字符串数组在对字符串的外部参照之前开始一点,在哪里使用了它,并且在哪里调用了using函数。


另一种可能性是我几天前在ARM android共享库中看到的东西。库中有一些字符串,每个字符串都紧接着函数名称,就像这样(转换为x86语法)。

errmsg    db 'Error in %s, file %s, line %d\n', 0
strtab    db 'opencachefile', 0
          db 'closecachefile', 0
          db 'getcacheentry', 0
          db 'putcacheentry', 0
          db 'delcacheentry', 0


从缓存中获取内容的函数使用了第三个这些字符串记录可能的错误。代码看起来像这样(再次从arm转换为x86):

...
mov    eax, offset strtab
add    eax, 29           ;<-- difference in bytes between 'open' and 'get'
push   eax
mov    eax, offset errmsg
push   eax
call   android_log_print


其他功能具有类似的构造,因此strtab被引用了5次(每个功能一个),并且每个字节的字节差都进行了调整。我真的不知道为什么编译器会这样做,但是也许您的代码中正在发生类似的事情。

评论


谢谢!这是一个很好的答案。请您告诉我汇编中的字符串数组可能是什么样子。另外,当您声明以下内容时,您是否可以详细介绍一下:您的字符串似乎具有来自0040C624的外部参照。什么是外部参照0040C624

–user222811
2015年5月31日20:40