我找到了想要的文本字符串:
.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