3

Why decompiling a delphi exe, is so easy, compared to others executables built with other programming languages/compilers?

BlackShadow
  • 1,005
  • 6
  • 19
  • 25
  • 9
    Why do you think it is easy? –  May 25 '11 at 19:54
  • http://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/DeDe.shtml – BlackShadow May 25 '11 at 19:56
  • Your link looks like the standard decompiler funcionalities to me. What is easy about that? – Hyperboreus May 25 '11 at 19:59
  • 2
    Decompilers of various quality are available for all compiled languages I'm aware of. Mostly the quality is pretty poor. –  May 25 '11 at 20:00
  • Yes, but some types of executables, especially exe's built with borland compilers, are better suited for decompiling (makes better result compared to a decompiled exe created with the c++ languages). Also, some types of decompilers can show the name of classes, windows, variables etc of exe's built with the vcl library This things cannot be done with a exe built with c++(mfc) – BlackShadow May 25 '11 at 20:05
  • 4
    Knowing the names of visual component classes (eg., `TMyForm`, `TEdit1`, etc.) don't help you know anything about the functionality of the application. Your claim that this makes it easier to decompile is nonsense - knowing that Delphi32 uses a window class named `TAppBuilder`doesn't mean you can write a new version of the Delphi IDE with the same capabilities. – Ken White May 25 '11 at 20:09
  • 2
    The program you link to creates a .pas file with *`assembler code`* inside. not really what I would call a decompiled program, just a disassembled one. It does nothing special. – Johan May 25 '11 at 20:23
  • 4
    @BlackShadow If I recall correctly DeDe is just a disassembler that understands a bit of Delphi metadata. Calling it a decompiler is misleading. – CodesInChaos May 25 '11 at 20:23

5 Answers5

18

There are a few things that help with reversing delphi programs:

  • You get the full form data including the name of event handler methods
  • All members with published visibility have metadata used with RTTI
  • The compiler is pretty bad at optimizing. It does no whole program optimization and the assembly is usually a straight forward translation of the original source with only minor optimizations. (At least it was in the versions I used, might have improved since then)
  • All classes, even those compiled with RTTI off have some level of metadata available. In particular it's possible to get the name and inheritance structure of classes. And for any instance of a class you happen to see in the debugger you can get its VMT and thus its class name.

Delphi uses textfiles describing the content of your form and hooks up event handlers by name. This approach obviously needs enough metadata to deserialize that textual representation of a from and hook up the eventhandlers by name.

An alternative some other GUI toolkits use is auto-generating code that initializes the form and hooks up the event handler with code. Since this code directly uses pointers to the eventhandlers and directly assigns to properties/calls setters it doesn't need any metadata. Which has the side-effect that reversing becomes a bit harder.

It shouldn't be too hard to create a program that transforms a dfm file into a series of hardcoded instructions that creates the form instead. So a tool like DeDe won't work that well anymore. But that doesn't gain you much in practice.

But figuring out which evenhandler corresponds to which control/event is still rather easy. Especially since stuff like FLIRT identifies most library functions. So you just need to breakpoint the one you're interested in and then step into the user code.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Yes, its exactly what i mean, but my question is why? why i can retrive the names of event handles while with others exe built with other languages (see C++)? – BlackShadow May 25 '11 at 20:29
  • 1
    That's not a question of the language, but more one of how your GUI toolkit/GUI designer works. But reversing the GUI part is rarely interesting. It just helps you to get to the parts of the code you're interested in quicker. – CodesInChaos May 25 '11 at 20:36
  • In the case of building with packages, it is probably even easier to get a complete list of RTL/VCL entrypoints. – Marco van de Voort Jun 09 '11 at 12:55
  • I think packages export all public functions using dll exports with a mangled name. But I expect FLIRT to work so well that this doesn't make much difference in practice. – CodesInChaos Jun 09 '11 at 13:13
17

The statement you make is false. Delphi is not particularly more easy to decompile than code produced by other mainstream compilers.

If you were able to prove that the results of decompiling a Delphi executable were of significantly higher quality than in other widely used languages then your question would carry more weight.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • My question is referred only to compiled executables (exe that contain assembly code, not IL such as .net) – BlackShadow May 25 '11 at 20:10
  • 3
    My answer stands. Where is your evidence that Delphi executable's are more successfully decompiled than MSVC ones? If your question was only meant to refer to compilers that emit native code, why didn't you say so? – David Heffernan May 25 '11 at 20:18
  • 3
    No need to be nasty. CodeInChaos describes the reasoning nicely. Basically, Delphi programs retain a lot more metadata than other native compilers (definitely more than e.g. VC/MFC programs), which makes reversing them easier. – Igor Skochinsky May 26 '11 at 15:49
  • @Igor The point is that the metadata isn't really worthwhile. In any case, I've yet to hear any evidence that anyone has successfully reversed a real app. Cosmin's story is telling. – David Heffernan May 26 '11 at 16:06
  • 1
    Cosmin's story is not really relevant. He tried to reverse a single function in a single DLL, it did not involve any metadata. Real Delphi apps have many classes for which most of details are available in RTTI: name, size, inheritance hierarchy, names of fields and handlers for UI events and so on. For example, here's what can be recovered from the executable for a single form: http://pastie.org/private/bexiwdctu7scsrafqqsw (done with an IDC script). This way you can restore almost complete layouts of many classes which speeds up reversing significantly. – Igor Skochinsky May 26 '11 at 16:27
  • @igor it must be the kind of programming that I do, but for me the value is all in the code and without that all the visual fluff is useless. – David Heffernan May 26 '11 at 16:39
  • 1
    When reversing, every scrap of information can be useful, "fluff" or not. Even isolated code functions have to interact with the rest of the program and the extra info you might have about that will help. – Igor Skochinsky May 26 '11 at 17:52
15

Story from the trenches: Decompiling a tiny Delphi DLL

I've been through a Delphi decompiling session myself. It was one of those fake-sounding "I lost my sources" thing, I really did lose the sources for a tiny Firebird UDF library. Now I do no better, I didn't jump right into decompiling because the library was so small and I knew a rewrite would be much faster.

This DLL exports a function that looks like this:

function udf_do_some_math(Number1, Number2:Currency): Currency;

After doing the sane thing and rewriting the function and doing some regression tests I discovered some obscure corner-cases where the new function's result wasn't the same as the old function's result! The trouble was, the new function's result was the correct result, the old DLL contained a BUG and I had to reproduce the BUG - with this function consistency is more important then accuracy.

Again, did the sane thing and tried to "guess" at the BUG. I knew it was a rounding issue but simply couldn't figure out what it was. Finally I decided to give decompilers I try. After all this was a small library, the entry-point was straight-forward and I didn't really need re-compilable code, nor 100% decompilation: I only needed enough to figure out the old BUG so I can reproduce it!

Decompiling failed! I tried lots of different decompilers, including a couple of "commercial" ones. Most produced what on the surface looked like good data, but not enough to figure out the old bug. The most promising one, the one with version specific knowledge of the VCL and RTL gave the worst failure: sure, it figured out the RTL calls, gave them names, but failed to locate the exported function! The one function I was interested in wasn't shown int the list of entry points, and it should have been straight forward since it's an exported function.

This decompiling attempt should have been easy because:

  • The code was fairly simple and not a lot of it.
  • It was a DLL with an exported function, none of the complexity you'd expect from an event-driven exe.
  • I wasn't interested in re-compilable code, I simply wanted to find an old bug so I can reproduce it.
  • I didn't ask for Pascal code, assembler would've been good enough.
  • I knew precisely what the code was doing and how it was doing it. It wasn't cryptic 3rd party code.

My solution

After decompilers failed me I turned to my own trusty Delphi IDE for debugging. I wrote a small Delphi program that directly imports the function from the DLL, created a fake Firbird memory manager DLL so my DLL can load, called my old function with the parameters I knew would give bad results, steped into the code using the debugger and closely watched the FPU registers. After a few failed attempts I finally noticed a value was popped from the FPU stack as integer where it shouldn't have been Integer so I had my BUG: I mistakenly defined an Integer local variable where I should have used Currency. Armed with that knowledge I was able to reproduce the bug.

Community
  • 1
  • 1
Cosmin Prund
  • 25,498
  • 2
  • 60
  • 104
5

Only thing that is easier in Delphi is retrieving VCLs. After using decompilers like DeDe you will get application user interface but without any logic. So if you want to retrieve only forms and buttons - Delphi is easier than other compilers, but if you want to know what is going on after clicking on the button you'll need to use ollydbg or other (debugger/disassembler) as for other languages that creates executables.

Jarek Bielicki
  • 856
  • 6
  • 16
-1

There are pros and cons. I am not sure what angle your referring to as being easier. There is also a huge difference in a 1 form simple application, versus a very in-depth application that has many forms and tons of classes and functions. It's like Notepad versus Office 2013 (given they were coded in delphi, just an example comparing complexity not language).

In a small app, having the extra information that Delphi apps "usually" contain can make it a breeze. However, in a large application it may "help", but you have a million calls to dig through. They may help you get in the near vicinity, but calls inside of calls inside of calls, then multiple returns used as jumps... makes you dizzy. Then if the app "was" packed or protected, some things can still be a garbled mess. While it may work programming wise, reading it can be a lot harder. I was in one the other day, where all of the strings were encrypted, so "referenced text strings" were no help, and the encryption was not a simple md5 or base64, it was some custom algorithm. Maybe an MD5 with a salt, then base64 encoded? I never could get to the exact method on the strings. I knew what some of them were supposed to be, but couldn't reproduce the method, even though it looked like it was base64, it was the base64 of the string already encrypted some how... I dont rely on text strings, but in a large large app, every little bit helps.

Of course, my interpretation of this question, was looking at a Delphi exe in OllyDbg. I could be off base on where you guys were going with this topic, but I feel in regards to Olly and reversing, I am on point (if that was what you were talking about) lol.

Wade
  • 3,757
  • 2
  • 32
  • 51