您的字符串似乎有一个来自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 字节,您可以使用它来查找字符串表(错误, at )。您可以通过查看其外部参照来找到字符串表本身的使用位置 - 从 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 次(每个函数中一次),并且在每个函数中调整了字节差异。我真的不知道为什么编译器会这样做,但也许您的代码中发生了类似的事情。