Re: Looking for disassembler, decompiler, discompiler or

Mikael Lyngvig <mikael@lyngvig.dk>
11 Sep 2001 23:15:25 -0400

          From comp.compilers

Related articles
Re: Looking for disassembler, decompiler, discompiler or mikael@lyngvig.dk (Mikael Lyngvig) (2001-09-11)
Re: Looking for disassembler, decompiler, discompiler or mikael@lyngvig.dk (Mikael Lyngvig) (2001-09-11)
| List of all articles for this month |

From: Mikael Lyngvig <mikael@lyngvig.dk>
Newsgroups: comp.compilers
Date: 11 Sep 2001 23:15:25 -0400
Organization: Lyngvig Family
Keywords: disassemble
Posted-Date: 11 Sep 2001 23:15:25 EDT

9/11/2001 6:20:20 AM, zuyihe@163.net wrote:


>Thank you guys for your reponses. I wonder if my former request is too
>hard to be practical so I just go directly to the problem that I
>couldn't get rid of.
>
> My advisor wants me to modify an executable by inserting several
>instructions (to the text section). You are only given
>executable. Jesus, what can I do? Does it sound a reasonable task?
>Man, it could be a Ph.D. thesis. Any idea to hack this bullshit?
>Thanks.


It is not that hard, but you'd have to get to know quite a bit about
the executable format, most likely ELF, before you could do it
properly. You'd basically have to change five different things:


1. The executable file headers. That's straightforward, but should be
done as the very last thing because it depends on the sizes of the
various tables.


2. The section table. The size of the modified section as well as
file offsets of trailing sections must be adjusted.


3. The symbol table. Offset of symbols above your insertion has to be
adjusted (the size of the inserted patch must be added). For most
symbols this is also pretty straightforward - if the symbol is in the
same section as where you've made your patch and the offset is greater
than or equal to the offset of your patch, the symbol needs to be
adjusted. I've worked much more extensively with COFF/ELF object
files than executables, so I'm not sure if there's a symbol issue at
all - supposedly, there shouldn't be anything important left in the
symbol table of an executable, but you'll have to check that you for
yourself.


4. The relocation table (fixups). Again, here's a difference between
object files and executables. Executables are probably fairly trivial
compared to object files, but the basic issue is the same: you have to
adjust the offsets of the fixups/relocations above your patch. E.g.,
the fixups that are associated with the text section in question and
whose offset is greater than or equal to the position of your patch.


5. The text section itself. That's piece of cake (assuming you've
somehow found the byte offset and size of the patch in that section).


If there's debug information attached to the executables, and it has
to remain valid, you might also have to parse that and perform a
similar modification of that. However, I don't think that's an issue
with ELF; I believe DWARF embeds references to the ELF symbol table so
that the DWARF info is "patched" as soon as you've patched the ELF
symbol table. You'd have to check into this yourself. Microsoft's
debug info format (Codeview) has its own redundant symbol table, for
historical reasons, so that it would need to be patched separately.


So, even though it is conceptually simple, there's a lot of details
that must be done right. I would suggest you wrote an executable file
loader, which reads the entire executable into memory and build a
"memory model" of that executable, which could be saved in any state.
E.g., you start out by creating and implementing an interface like
this:


class cHeader; // executable header fields
class cFixup; // fixup - type, offset, etc.
class cSymbol // symbol - type, offset, etc.


class cSection // section - data, size, and flags
{
public:
      ...


      void Patch(long Offset, long Size, const void *pData);


private:
      cSymbol *pSymbols; // symbols associated with the section
      cFixup *pFixups;
      void *pData;
        long Size;
};




class cExecutable
{
public:
        cExecutable(void);
        ~cExecutable(void);


        void Load(const char *pFilename);
        void Save(const char *pFilename);


        void Patch(const char *pSectionName, long Offset, long Size, const void *pData);


private:
      cHeader Header;
      cSection *pSections;
};


So, your first step would be to do things like:


      cExecutable Exec;


      Exec.Load("oldexe");
      Exec.Save("newexe");


When and works (you can run the new executable without problems and
your manual verification of the written file makes you believe that it
is indeed valid), you're pretty much set on the path to success. Then
you just need to implement the actual Patch() method itself.


> The platform is Linux on PowerPC or Solaris on Sun.
>[This is what's known as binary patching. Back in the Heroic Era of
>the 1950s and 1960s, any programmer could squint at a compiled program
>and patch in a few instructions, sticking in a few jumps if need be
>if there wasn't room. It's not THAT hard. -John]


Well, it is a bit harder today, because some companies have actually
taken out patents on patching executable files. As a result, you
cannot just go ahead and do patches like its been done for 30 or 40
years, you have to make sure you're not stepping on somebody's
patents. Guess it is not a big deal for a Ph. D. thesis, but for a
business it would be. Companies like Rational Software Corporation
actually earns part of their living from patching people's
executables, so it is not at all such an unreasonable request.


P.S. Perhaps my email's a bit long, but this happens to be an area
that interests me quite a bit. Hope it helps, you're welcome to drop
me a note privately, if you need clarification of anything.


-- Mikael
-- Wonder why nobody ever took patent on malloc() and free()?


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.