3

I'm trying to disassemble an application (built from a Chinese company in English).

I find the text string I want:

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

But, I cannot locate it in the code anywhere. It's strange some text strings are found but others are not.

FYI: The application also loads a custom .dll file. The text is located in the main exe file's .rdata segment, but I just cannot see it in the code. I've tried with other disassemblers but I am using IDA.

7

Your string seems to have an xref (cross reference, see below) from 0040C624. This string might just be an entry in an array of error strings, with the array itself beginning just a little before 0040C624. Your original source code may have looked like this:

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);
}

If you compile this (i used gnu C on linux, gcc -m32 xref.c) and load the object code into IDA, it becomes (irrelevant parts omitted):

.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

You see that each string has a pointer entry in the data section, and the ascii data in the rodata (read only data) section. And each of the ascii strings has an xref (cross reference) to the pointer that points to it - this is not a part of the binary; ida detects where each string is referenced, and generates the "backreferences", or xrefs.

The important thing is: you can use this to find the string table (errors, at 0x08000034) if you have only the ascii bytes. And you can find where the string table itself is used by looking at its xref - from the print_error_message function. In contrast, the unused string does not have an xref, because it isn't used anywhere.

Ida will allow you to double-click on the xref to move to where it 'comes from' to navigate easily.

I'd check if you have an array of strings that starts a bit before the xref to your string, where it gets used, and possibly where the using function gets called.


Another possibility is something that i saw a few days ago in an ARM android shared library. The library had some strings holding function names, directly after each other, like this (translated to x86 syntax)

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

The function that got something from cache used the third of these strings to log a possible error. The code looked like this (again, translated from arm to 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

The other functions had similar constructs, so strtab was referenced 5 times (one in each function), and the byte difference adjusted in each of them. I sincerely don't know why a compiler would do this, but just maybe something similar is going on in your code.

  • Thank you! This is a very good answer. Please could you show me what maybe an array of strings might look like in Assembly. Also, could you go into more details when you state: Your string seems to have an xref from 0040C624. what is an xref 0040C624 – user222811 May 31 '15 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.