C - How to create a template in a code segment to recognize it in a memory dump?

I delete my RAM (part of it is just a code segment) to find where function C is located. I don’t have a map file and I don’t know what loading / initialization procedures do.

I load my program into RAM, and then if I reset the RAM, it is very difficult to find exactly where the function is located. I would like to use different template assemblies in the C source to recognize them in a memory dump.

I tried to run each function with a different first variable containing the name of the function, for example:

char this_function_name[]="main"; 

but it does not work, because this row will be placed in the data segment.

I have a simple 16-bit RISC processor and an experimental proprietary compiler (without GCC or any known ones). The system has 16 MB of RAM shared by other applications (bootloader, bootloader). It is almost impossible to find a specific sequence N NOP or smth. like 0xABCD. I would like to find all the functions in RAM, so I need unique identifiers for the functions visible in the RAM dump.

What is the best sample for a code segment?

+4
source share
7 answers

If it were me, I would use a character table, for example. "nm a.out | grep main". Get the real address of any function you want.

If you really don't have a character table, make your own.

 struct tab { void *addr; char name[100]; // For ease of searching, use an array. } symtab[] = { { (void*)main, "main" }, { (void*)otherfunc, "otherfunc" }, }; 

Look for the name, and the address will immediately start it. Go to address .; -)

+7
source

If your compiler has a built-in asm, you can use it to create a template. Write a few NOP instructions that you can easily recognize by the operation codes in the memory dump:

 MOV r0,r0 MOV r0,r0 MOV r0,r0 MOV r0,r0 
+3
source

Numeric constants are placed in a code segment encoded in functional instructions. So you can try using magic numbers like 0xDEADBEEF etc.

those. here is a collapsible view of a simple C function with Visual C ++:

 void foo(void) { 00411380 push ebp 00411381 mov ebp,esp 00411383 sub esp,0CCh 00411389 push ebx 0041138A push esi 0041138B push edi 0041138C lea edi,[ebp-0CCh] 00411392 mov ecx,33h 00411397 mov eax,0CCCCCCCCh 0041139C rep stos dword ptr es:[edi] unsigned id = 0xDEADBEEF; 0041139E mov dword ptr [id],0DEADBEEFh 

You can see that 0xDEADBEEF turns it into a function source. Note that what you actually see in the executable depends on the CPU match (tx. Richard).

This is an x86 example. But RISC processors (MIPS, etc.) have instructions that move directly to the registers - these direct users can also have special recognized values ​​(although only for 16-bit for MIPS, IIRC).


Psihodelia - It’s getting harder and harder for you to catch your intention. Is this just one feature you want to find? Then you can’t just post 5 NOPs one by one and look for them? Do you control the compiler / assembler / linker / loader? What tools are at your disposal?

+1
source

As you noted, these are:

 char this_function_name[]="main"; 

... will result in setting the pointer in your stack to the data segment containing the string. However, this:

 char this_function_name[]= { 'm', 'a', 'i', 'n' }; 

... most likely will put all these bytes on your stack so that you can recognize the line in your code (I just tried this on my platform).

Hope this helps

+1
source

How about a completely different approach to your real problem that finds a particular block of code: Use diff.

Compile the code once with the function enabled, and comment once with it. Produce RAM dumps of both. Then separate the two dumps to see what has changed - and this will be a new block of code. (You may need to do some dump processing to remove memory addresses in order to get a clean diff, but the order of the instructions should be the same anyway.)

+1
source

Why not make each function reset its own address. Something like that:

 void* fnaddr( char* fname, void* addr ) { printf( "%s\t0x%p\n", fname, addr ) ; return addr ; } void test( void ) { static void* fnaddr_dummy = fnaddr( __FUNCTION__, test ) ; } int main (int argc, const char * argv[]) { static void* fnaddr_dummy = fnaddr( __FUNCTION__, main ) ; test() ; test() ; } 

When creating fnaddr_dummy static, a dump is performed once for each function. Obviously, you will need to adapt fnaddr () to support any output or logging that you have on your system. Unfortunately, if the system performs lazy initialization, you will only get the addresses of the functions that are actually being called (which may be good enough).

+1
source

You can run each function by calling the same dummy function as:

void identFunction (identifier unsigned int) {}

Each of your functions will call identFunction with a different parameter (1, 2, 3, ...). This will not give you the magic map file, but when you check the code dump, you should quickly find out where the identFunction function is, because there will be many transitions to this address. Then scan these jumps and check before jumping to see which parameter is passed. Then you can create your own file. With some scenarios, this should be pretty automatic.

0
source

All Articles