Reverse engineer ELMConfig.exe

Post Reply
Posts: 764
Joined: 08 Feb 2019, 12:25

Reverse engineer ELMConfig.exe

Post by Go4IT »

Hey guys, i've recently startet to look at the famous ELMConfig Tool. I've used this over many years and still today it has some advantages over ForScan at some points. But it wasn't fully translated to English and this is what i really like to have for so long. So i decided to dig into it, as an example of how to reverse engineer software. Others would call it "hacking", which is also true, but it's not my intention to steal something, rather to make it's use even better ;-)

To i simply opened ELMConfig.exe in HxD to have a look what's inside, but could not find any valuable text there. So i assume it's packed or crypted somehow. Next i loaded the EXE into Ghidra, which is a reaaally nice (and free!) tool. It tell us some internals of the EXE after importing like:
- The EXE is made from VisualStudio as an 32 Bit PE (Portable Executeable). The version i've choosen is "0.2.018".

A executeable is generated by an compiler which, in the end, creates direct machine executeable code from an programming language into a file. The code itself must know about the memory location (address) of functions, variables, constants. Therefore in the machinecode it has absolute memory locations, where the exe is build. Now, you can do this with one program, but if you need to run another program in parallel, the code must be relocated to a different memory address where it does not collide with the running one. This is where "Portable Executeable" comes into play.

With PE it is possible for the loader (the part in the OS which starts a program) to relocate the code to another address. Ghidra tell us that this target should be loaded at 0x400000 and is NOT Relocatable, which seems like a contradiction to PE itself.

Usually software utilizies several libraries to do it's work, this is also true for ELMConfig. Beneath some DLLs shipped with it, it could make use of libs provided by the Operatingsystem (Windows). A linker could integrated needed libs of a program at compiletime directly into the resulting file, this is known as "static linking". Or it could just refer to it. Then it will be loaded by the loader on runtime, which is called "dynamic linking". The pro and cons of this is that dynamic linked binaries could me much smaller, but static linked are runable without extra libs to be installed. In our case, ELMConfig makes use of some libs and Ghidra tells us which:

Code: Select all

----- Loading /C:/temp/Elmconfig-Hack/ELMConfig.exe -----
Delay imports detected...
Searching for referenced library: USER32.DLL ...
Found and imported external library: C:\WINDOWS\SysWOW64\USER32.DLL
Searching for referenced library: OLEAUT32.DLL ...
Found and imported external library: C:\WINDOWS\SysWOW64\OLEAUT32.DLL
Searching for referenced library: COMCTL32.DLL ...
WARNING! Using existing exports file for COMCTL32.DLL which may not be an exact match
Found and imported external library: C:\WINDOWS\SysWOW64\COMCTL32.DLL
Searching for referenced library: ADVAPI32.DLL ...
Found and imported external library: C:\WINDOWS\SysWOW64\ADVAPI32.DLL
Searching for referenced library: KERNEL32.DLL ...
Found and imported external library: C:\WINDOWS\SysWOW64\KERNEL32.DLL
Searching for referenced library: GDI32.DLL ...
Found and imported external library: C:\WINDOWS\SysWOW64\GDI32.DLL
Finished importing referenced libraries for: ELMConfig.exe
Next you can double-click the imported EXE and the Ghidra-Disassembler opens ("Dragon appears"). First i start an analysis to see what comes up without further efforts ;-) Ghidra done it's job and presents a bunch of informations. The first thing it shows it the "Headers" section of the file. Here we find out more about the exe. First the "MZ" magic, which is prepend to all exe files.

Now i'm going to find the start of the program. This is referenced in the optional PE header by the parameter "AddressOfEntryPoint" (0x527ad), which is a relative offset to the value "BaseOfCode" (0x400000) and so it starts at 0x4527ad:

Code: Select all

                             *                          FUNCTION                          *
                             undefined entry()
             undefined         AL:1           <RETURN>
                             entry                                           XREF[2]:     Entry Point(*), 004000d8(*)  
        004527ad 60              PUSHAD
        004527ae be 8f 07        MOV        ESI,0x40078f
                 40 00
        004527b3 8d be eb        LEA        EDI,[ESI + 0xffffafeb]
                 af ff ff
        004527b9 57              PUSH       EDI
        004527ba 83 cd ff        OR         EBP,0xffffffff
        004527bd eb 10           JMP        LAB_004527cf
        004527bf 90              ??         90h
        004527c0 90              ??         90h
        004527c1 90              ??         90h
        004527c2 90              ??         90h
        004527c3 90              ??         90h
        004527c4 90              ??         90h
        004527c5 8a              ??         8Ah
        004527c6 06              ??         06h
        004527c7 46              ??         46h    F
        004527c8 88              ??         88h
        004527c9 07              ??         07h
        004527ca 47              ??         47h    G
        004527cb 01              ??         01h
        004527cc db              ??         DBh
        004527cd 75              ??         75h    u
        004527ce 07              ??         07h
                             LAB_004527cf                                    XREF[1]:     004527bd(j)  
        004527cf 61              POPAD
        004527d0 90              NOP
        004527d1 90              NOP
        004527d2 50              PUSH       EAX
        004527d3 51              PUSH       ECX
        004527d4 74 05           JZ         LAB_004527db
        004527d6 83 c8 05        OR         EAX,0x5
        004527d9 eb 02           JMP        LAB_004527dd
Let's see if we can find out what this is. I would expect some kind of unpacking algo. Besides of the code, Ghidra gives a nice flow-graph, here just a sample:
You do not have the required permissions to view the files attached to this post.
Post Reply