recos icon indicating copy to clipboard operation
recos copied to clipboard

How to find 'debug_logger' function?

Open mediotex opened this issue 1 year ago • 37 comments

Where should be placed the FIDB files (ecos-mips.be.32.fidb and ecos-mips.le.32.fidb) in Ghidra directory? Also about eCOS Broadcom Function Auto-Renaming (Ghidra) - BcmDebugLogsRenameFunctions.java script: how to find 'debug_logger' function in firmware for auto-renaming?

mediotex avatar Jul 04 '24 23:07 mediotex

I just had the same problem, and managed to figure it out:

  1. First, click Search > Memory, and search for any named function (one that worked for me was setBridgePortEnable). Make sure format is set to "string" and memory block types is set to "all blocks" Screenshot
  2. Right-click on the string name, and click References > Show references to (name) Screenshot
  3. Now it should be clear which function it is (but obviously it won't already be named like mine is) Screenshot

Anonymous941 avatar Jul 20 '24 15:07 Anonymous941

I searched for setBridgePortEnable, but the search did not yield results. Same for 'debug_logger'. In general, I have to find a specific function that a) actually exists in my eCos version and b) get it exact name, correct? Then, using that function as a basis, define other functions. I'm correct? As noted in the recos manual, the FunctionID database files work for eCOS 1.0, 2.0, and parts of 3.0. My eCos revision is 3.0.2, so possible, the FIDB files are not valid. Is it possible to find an exact name of target function using the CLI shell? I have eCos BFC Application Layer Revision: 3.0.2

mediotex avatar Jul 20 '24 22:07 mediotex

Is it possible to find an exact name of target function using the CLI shell?

Unfortunately, there isn't a direct way to do that that I know of

In general, I have to find a specific function that a) actually exists in my eCos version and b) get it exact name, correct?

That's right, but you only need to find one named function (any will do), and then using that named function you can find debug_logger. Once you find debug_logger, the script should be able to automatically find the rest.

Is this a bootloader image or an image1/image2 image? If it's a bootloader image, you can try searching for the function names listed here. If none of those have any results, you can try the instructions below

If it's an image1/image2 image, then it might not have the function named setBridgePortEnable. You can try going to Window > Defined strings and looking for anything that looks like a function name, then follow my instructions in the previous comment

If Defined strings is empty, make sure you unpacked it properly with ProgramStore (by using the -f and -f2 arguments), applied FunctionID and set up memory mappings

Anonymous941 avatar Jul 21 '24 16:07 Anonymous941

image1.out is actual image1 (not bootloader) which I dumped from RAM using bcm2dump. Then I decompressed it to image1.out use ./ProgramStore -f image1.bin -x

In Window > Defined strings, I tried strings that looks like a function name, there are many potential candidates (GetSingletonInstance, BcmAgentCoreHelper, BcmAmdFlashDevice, BcmArpFilterSnoop, getAPExpAlgInfo), but in all cases when right-click on the string name, and click References > Show references to (name), there are only "Show Reference To Address", not to function name. By the way, there are errors in 2 recos scripts: BcmDebugLogsRenameFunctions.java and BcmRenameLabelVTable.java: when I placed it via Ghidra Script Manager, it show me error (red color) and does not allow select it as valid scripts:

BcmDebugLogsRenameFunctions.java:34: error: class DebugLogsAnnotateFunctions is public, should be declared in a file named DebugLogsAnnotateFunctions.java
public class DebugLogsAnnotateFunctions extends GhidraScript {
       ^
BcmRenameLabelVTable.java:25: error: class RenameLabelVTable is public, should be declared in a file named RenameLabelVTable.java
public class RenameLabelVTable extends GhidraScript {
       ^
skipping /home/teknos/ghidra_scripts/BcmRenameLabelVTable.java
skipping /home/teknos/ghidra_scripts/BcmDebugLogsRenameFunctions.java

As far I understand, it's because Name of public class must match the name of .java file in which it is placed (like public class Foo{} must be placed in Foo.java file). So either I should to rename file from BcmDebugLogsRenameFunctions.java to DebugLogsAnnotateFunctions.java or rename the class from public class DebugLogsAnnotateFunctions { to public class BcmDebugLogsRenameFunctions { I've chosed the second way. Same for another script.

Also, what's not clear with image1.out in Ghidra: part of functions not shown in Symbol Tree pane "Functions" Label: there are misssing FUN_007 label. Why it missing and where is these functions? Qab7TgnZ

mediotex avatar Jul 21 '24 22:07 mediotex

image1.out is actual image1 (not bootloader) which I dumped from RAM using bcm2dump. Then I decompressed it to image1.out use ./ProgramStore -f image1.bin -x

Is there also an image2? If so, it might (but I'm not sure) be required to get the full firmware. That's what I did for my router and was able to decompile it, try running ./ProgramStore -f image1.bin -f2 image2.bin -x, then using that file. Maybe that will have setBridgePortEnable

when right-click on the string name, and click References > Show references to (name), there are only "Show Reference To Address", not to function name.

That should probably work as well, try that. If it doesn't work, you can try searching for the function names you see now (see my first comment)

As far I understand, it's because Name of public class must match the name of .java file in which it is placed (like public class Foo{} must be placed in Foo.java file). So either I should to rename file from BcmDebugLogsRenameFunctions.java to DebugLogsAnnotateFunctions.java or rename the class from public class DebugLogsAnnotateFunctions { to public class BcmDebugLogsRenameFunctions { I've chosed the second way. Same for another script.

That's exactly what I did, and it fixed it for me too (and the script successfully extracted the function names, so there aren't any other issues). It's probably because the scripts are for an old Ghidra version

Anonymous941 avatar Jul 21 '24 23:07 Anonymous941

Yes, there is image2. Same size, but different md5. Normally, the second image in cable modem is used as a backup if something happens with image1. I figured they should be identical. But not in this case: they are differs in MD5, and image2 has SIP in its name . I decompressed it ./ProgramStore -f image1.bin -f2 image2.bin -x and will take a look tomorrow.

mediotex avatar Jul 22 '24 00:07 mediotex

Normally, the second image in cable modem is used as a backup if something happens with image1. I figured they should be identical.

I didn't know that, for me it's a different size so maybe it varies by router

Anonymous941 avatar Jul 22 '24 00:07 Anonymous941

the image decompressed by ./ProgramStore -f image1.bin -f2 image2.bin -x has the same MD5 as image1 - that is, they are the same. Decompressed image2(with SIP) is a newer version, I'll use it. It's not fully clear, how to split RAM in two regions: .text (code) and .data (data). image2 memory layout is as follows:

.text start: 0x80004000
.text end: 0x8079e4d0
.text length: 0x79a4d0
.data start: 0x8079e4d4
.data end: 0x8093e220
.data length: 0x19fd4c
.bss_start: 0x80aad090
.bss_end: 0x80d19760
stack start: 0x80b15660
stack end: 0x80b19660

In above example to set memory mapping, the Start Address is 80004000, but my is 00000000. Should I change this and what to specify in address fields? Block Length in screenshot means memory layout parts length? Screenshot_2024-07-22_18-32-40

mediotex avatar Jul 22 '24 13:07 mediotex

I find two functions, BcmAmdFlashDEvice and UcdMsgEvent, but as I noted in previous posts, it only "Show Reference To Address", not to function name, and no references found to that addresses. Maybe addresses are wrong.

mediotex avatar Jul 22 '24 16:07 mediotex

It's not fully clear, how to split RAM in two regions: .text (code) and .data (data). My memory layout is as follows:

Ah, I think that's been the issue all along. I found the instructions confusing too, and the screenshots on the page were extremely helpful (albeit still confusing). Here's how I did it:

  • The start address is set when you import the firmware image into Ghidra. Unless you specifically change it, it'll default to 0x00000000, which is why that's the starting address for you. You have to click the house icon and change it to the value of .text start
  • For some reason, the Ghidra's length is always 1 more then the recos script says. So set the end to .text end, and length in Ghidra should automatically be set to 1 more then .text end
  • For the new block, set its name to .data, and leave length as it is
  • Now click split again and name it .bss, set its start address to .bss_start, and its length to .bss_end - .bss_start. You have to manually do this in a hexadecimal calculator, in this case it's 0x80d19760 - 0x80aad090 = 0x26c6d0
  • Click split a final time, name it stack, and do the same thing as .bss (length is 0x80b19660 - 0x80b15660 = 0x4000)

Once all these are set, hopefully it will finally tell you where those strings are referenced

Anonymous941 avatar Jul 22 '24 18:07 Anonymous941

I'm confused in the 4 step

Now click split again and name it .bss, set its start address to .bss_start, and its length to .bss_end - .bss_start.

Should I select and split here the ram or .data section, or click Add a new block to memory?

recos instruction says "Once that’s done, we can add new regions. We can add the BSS as an overlay"?

Screen

mediotex avatar Jul 22 '24 20:07 mediotex

Not sure if its correct:

Screen2 I don't see .text section

mediotex avatar Jul 22 '24 21:07 mediotex

Should I select and split here the ram or .data section, or click Add a new block to memory?

Start by splitting ram and data, then use Add a new block to memory for .bss and stack

I don't see .text section

That only exists in the map_memory.py's output, not in Ghidra. For Ghidra, it's called ram

Not sure if its correct:

Here's what I have:

Screenshot

Here's the map_memory.py output:

.text start: 0x80004000
.text end: 0x80d5e618
.text length: 0xd5a618
.data start: 0x80d5e61c
.data end: 0x80fc64d0
.data length: 0x267eb4
.bss_start: 0x8140ece8
.bss_end: 0x81642430
stack start: 0x8151a6e8
stack end: 0x8151e6e8

Your screen looks mostly correct, but there's an off-by-one error, "length" should be what you see in map_memory.py and "end" should be one off. eg ram's length should be 0x79a4d0, not 0x79a4d1

Anonymous941 avatar Jul 22 '24 23:07 Anonymous941

Your screen looks mostly correct, but there's an off-by-one error, "length" should be what you see in map_memory.py and "end" should be one off. eg ram's length should be 0x79a4d0, not 0x79a4d1

I'm not sure if ram length should be specified 0x79a4d0: since if I set "Block Length" to 0x79a4d0, ghidra automatically recalculates the "End Address", and it will be 0x8079e4cf, not 0x8079e4d0 that was specified in map_memory.py output.

mediotex avatar Jul 24 '24 12:07 mediotex

@mediotex The screenshots in the recos article show end, not length, being one off from the map_memory.py output. Both cause Ghidra to calculate the other

Anonymous941 avatar Jul 25 '24 20:07 Anonymous941

Ok, got it. I adjusted Memory Map and re-analyzed image. I find function s_BcmAmdFlashDevice_807a316c: how to rename function and to which one?

reference

Screenshot_

What if that logging function is not available in the code? For example, I can't find in code any strings called debug_logger. How did you rename the function and to what name in your post?

mediotex avatar Jul 26 '24 13:07 mediotex

There are available functions s_BcmAgentDescriptor::Bind_80868acc, s_BcmEcosSocket_808a0014 but no any debug_logger string - can you explain what specifically should be renamed? In script description noted:


// Identify calls to debug logging functions, re-construct the debug
// logging parameters and rename the calling function based on that
// string.
//
// Example: a function do: debug_logger(2, "Entering func: BcmEcosSocket::Bind"),
// we can consider the calling function is BcmEcosSocket::Bind.

It's not clear at all what should be renamed there.

mediotex avatar Aug 01 '24 15:08 mediotex

Sorry for the delay, I forgot to check my GitHub notifications

What if that logging function is not available in the code? For example, I can't find in code any strings called debug_logger. How did you rename the function and to what name in your post?

There isn't actually a debug_logger string in any router; you have to manually find and rename it yourself in Ghidra (recos just calls it that). My screenshot showed it after I already renamed it, but you have to find it from context, since there aren't any strings. You can tell which function it is because it always has the function's name passed into it, so you just had to find one function with a string (which you have) and then you should be able to figure out

After you find that one function, then these recos scripts will simply rename everything else (that it can), no more manual renaming required

Judging from your screenshot, you're 99% of the way there - just right-click on FUN_802da918 in the disassembly, choose Rename Function, and name it debug_logger yourself. Then hopefully you should be able to just run the BcmDebugLogsRenameFunctions script and it will rename all the other functions! If it fails, try renaming FUN_802714f4 to debug_logger instead of FUN_802da918

Anonymous941 avatar Aug 03 '24 16:08 Anonymous941

Oh, that changes things. Is this what I should get? Not so many, only 36 functions.

rename-func

And for C++ vtable Auto-Renaming: should I just run BcmRenameLabelVTable.java?

mediotex avatar Aug 04 '24 20:08 mediotex

Is this what I should get? Not so many, only 36 functions.

I don't think so, I got hundreds of functions. Can you show what the function names are on the symbol tree? It should be under Labels at the top. Also, can you show a screenshot of the decompile window scrolled to the right?

And for C++ vtable Auto-Renaming: should I just run BcmRenameLabelVTable.java?

Yes, you can just execute it after they're renamed (but I'm not sure that it worked correctly)

Anonymous941 avatar Aug 04 '24 20:08 Anonymous941

Not sure, how to expand functions tree to show all. Window > Functions: I have total 31813 functions, but they were already present there (just after I've analyzed image), before I ran the script. From the recos author's web pages appears that there are a few debug_loggers (up to 5?). Also, I have a lot of FID_conflict:_GLOBAL__I$52000_files labels.

Screen3

Screen4

Screen1

mediotex avatar Aug 04 '24 22:08 mediotex

I used the ghidra loader for ecos, and it does all the work. The problem is, When I try to load it using angr framewrok, i could not get the same functions addresses. have anyone of you face the same issue?

abduqasem avatar Aug 05 '24 05:08 abduqasem

From the recos author's web pages appears that there are a few debug_loggers (up to 5?)

Not sure what you mean...

Window > Functions: I have total 31813 functions, but they were already present there (just after I've analyzed image), before I ran the script

I meant under "Symbol Tree" (shown in your screenshot), there should be something you can expand called "Labels"

The function in your screenshot (FUN_8004578) should definitely be automatically renamed by the script to BcmAndFlashDevice, but for some reason it's not. debug_logger is definitely the right function, so the only reasons I can think of is either the memory map is incorrect, or there's a bug in recos. @ecos-wtf any ideas?

Anonymous941 avatar Aug 05 '24 12:08 Anonymous941

From document, chapter "Automated Function Renaming", we can see that there are a few 'debug_logger' names - debug_logger2, debug_logger5, in next pics debug_logger3, debug_logger4: not sure what this mean, but @ecos-wtf explanations are unclear in this point.

debug_logger_2

Here is a function tree expanded. For Memory Map I used values from script, and I only added "stub entry vector" block as shown in pic.

mediotex avatar Aug 05 '24 17:08 mediotex

Hi ! I was AFK for the last 3 months, I'll look into this in the coming days :)

qkaiser avatar Sep 24 '24 07:09 qkaiser

Hi ! I was AFK for the last 3 months, I'll look into this in the coming days :)

btw thanks for making these tools! They've been really helpful for modding my router

Anonymous941 avatar Sep 24 '24 14:09 Anonymous941

Where should be placed the FIDB files (ecos-mips.be.32.fidb and ecos-mips.le.32.fidb) in Ghidra directory?

You can put the FIDB files under ./Ghidra/Features/FunctionID/data/ or you can import it manually using the GUI (Tools -> Function ID -> Attach existing FIDB).

Also about eCOS Broadcom Function Auto-Renaming (Ghidra) - BcmDebugLogsRenameFunctions.java script: how to find 'debug_logger' function in firmware for auto-renaming?

All the debug_logger functions are function that were manually reversed and renamed as explained by @Anonymous941 . They're not present like this when you load the firmware. x-referencing debug strings usually does the trick to find these functions. You can choose a different name too, just edit the Java files to reflect that.

qkaiser avatar Sep 26 '24 19:09 qkaiser

As noted in the recos manual, the FunctionID database files work for eCOS 1.0, 2.0, and parts of 3.0. My eCos revision is 3.0.2, so possible, the FIDB files are not valid.

I don't think there were lots of changes between revisions 3.0 and 3.0.2 so most standard functions will be matched by Function ID. The FIDB is built for MIPS targets so make sure that's what your firmware is running on.

qkaiser avatar Sep 26 '24 19:09 qkaiser

From document, chapter "Automated Function Renaming", we can see that there are a few 'debug_logger' names - debug_logger2, debug_logger5, in next pics debug_logger3, debug_logger4: not sure what this mean, but @ecos-wtf explanations are unclear in this point.

These are just logging functions that were manually renamed during the reversing process. They're named differently because they have different signatures (which the Ghidra script needs to know since it's resolving the log string argument using Ghidra's API).

qkaiser avatar Sep 26 '24 19:09 qkaiser

I used the ghidra loader for ecos, and it does all the work. The problem is, When I try to load it using angr framewrok, i could not get the same functions addresses. have anyone of you face the same issue?

Can you expand on that ? Any specific reason you want to use angr rather than Ghidra for this ?

qkaiser avatar Sep 26 '24 19:09 qkaiser