Reversing: Secrets of Reverse Engineering

Category: Programming
Author: Eldad Eilam, Elliot J. Chikofsky
4.7
All Stack Overflow 15
This Year Stack Overflow 2
This Month Stack Overflow 7

Comments

by kervin   2019-07-21

You're getting into "Anti-reversing techniques". And it's an art basically. Worse is that even if you stomp newbies, there are "anti-anti reversing plugins" for olly and IDA Pro that they can download and bypass much of your countermeasures.

Counter measures include debugger detection by trap Debugger APIs, or detecting 'single stepping'. You can insert code that after detecting a debugger breakin, continues to function, but starts acting up at random times much later in the program. It's really a cat and mouse game and the crackers have a significant upper hand.

Check out... http://www.openrce.org/reference_library/anti_reversing - Some of what's out there.

http://www.amazon.com/Reversing-Secrets-Engineering-Eldad-Eilam/dp/0764574817/ - This book has a really good anti-reversing info and steps through the techniques. Great place to start if you're getting int reversing in general.

by anonymous   2019-07-21

You cant get variable names back. TReverse engineering is very difficult to do, recommend this book - http://www.amazon.co.uk/Reversing-Secrets-Engineering-Eldad-Eilam/dp/0764574817/ref=sr_1_1?ie=UTF8&qid=1353436851&sr=8-1

by anonymous   2019-07-21

If it's as foreign to you as it seems, I don't think a debugger or disassembler is going to help - you need to learn assembler programming first; study the architecture of the processor (plenty of documentation downloadable from Intel). And then since most machine code is generated by compilers, you'll need to understand how compilers generate code - the simplest way to write lots of small programs and then disassemble them to see what your C/C++ is turned into.

A couple of books that'll help you understand:-

  • Reversing
  • Hacking = The Art of Exploitation
by anonymous   2019-07-21

This is most likely C++, not plain C. That is exactly what Visual C++-generated virtual method calls look like. I would say that:

  • dword_10087418 is a pointer to an object. It is either a global or static variable, not a local one.
  • That object has a virtual method table, and the code is calling the second function in that table.
  • Assuming Hex-Rays has identified the function arguments correctly, the function being called takes one 32-bit argument. The return type is not clear.
  • The C++ call was most likely very simple, similar to SomeClass::Instance->func(arg).

If you are not familiar with the C++ object layout, you should read C++ Under the Hood , Reversing: Secrets of Reverse Engineering or Inside the C++ Object Model. The IDA Pro Book also has a brief section on the topic.


If you want a brief summary, read on. Keep in mind that all of this is an implementation detail of MSVC, other compilers do it differently and they can freely change it as they please. (Also, I'm simplifying things by not mentioning virtual/multiple inheritance). When a class uses virtual functions, the compiler builds a table of all such functions in that class and puts a pointer to that table as the first hidden member of each object of that class. Then, calling the virtual function from the table is as simple as:

mov ecx, esi   ; pretend that esi contains a pointer 
               ; to the object whose method is being called
               ; also known as "this"
               ; __thiscall functions expect to find this pointer in ecx
               ;  and all later arguments on the stack
mov edx, [ecx] ; get the vtable address
push edi       ; set up some integer-sized argument
call [edx + 4] ; call the second function in the vtable

And that is basically what that line of code is doing:

(*(int (__thiscall **)(int, int))(*(_DWORD *)dword_10087418 + 4))(dword_10087418, v11)
                                  ^-----------------------^
                                  dereference pointer to get the address of the vtable
                                  (it's the first piece of data in the object)
                                 ^-----------------------------^
                                 add 4 bytes to get address of the second function
^------------------------------------------------------------------------------------^
cast that pointer to a particular function pointer and call it
(cast is invisible in assembler code, so it's just a call)

Note that since the member function needs access to this, the compiler has to pass it as well. It's a detail that's not visible in C++, but this is treated like an additional argument for the function - hence you see two arguments but the function only takes one (MSVC's thiscall convention mandates that this pointer is passed in ecx). IDA doesn't bother hiding that pointer because that would get confusing.


More advice: Get the ms_rtti script for IDA and run it to find the virtual method tables in the DLL, then search for other references to dword_10087418 to see what values are written to it - you should be able to determine which vtable is associated with that object and then figure out which function is being called.

You can make Hex-Rays show the code in a more readable fashion if you define stub struct types for the class and the vtable in question, then tell IDA that the pointer uses that struct type.

by AB Kolan   2018-03-19

You might also want to have a look at OllyDbg which is a 32-bit assembler level analysing debugger. It is used to analyze binary code in scenarios where you do not have a source code. It is light weight debugger. OllyDbg is a shareware so you can download & use it for free..!!

Visit OllyDbg is home page here

PS: Back in the day crackers used SoftICE from NuMega for debugging into an executable & grab a snapshot at the values of registers. SoftICE was an advanced debugger. It was definitely the favorite tool for the crackers. I don't know about the present status of the product. NuMega's site had no information about it. I may have overlooked it but I could not find it. I recommend that you get your hands on a legacy version (4.0x) of SoftICE & apply the WindowsXP patch for SoftICE. Working with SoftICE is something of an "experience".

Further Read: Reversing: Secrets of Reverse Engineering by Eldad Eilam

by AviewAnew   2018-03-19

Reference (All Levels)


Beginner

Intermediate

  • Modern C — Jens Gustedt (2017). Covers C in 5 levels (encounter, acquaintance, cognition, experience, ambition) from beginning C to advanced C. It covers C11 threads and atomic access, which few other books do and not all compilers recognize in all environments.

Expert


Uncategorized


Warnings

Be wary of books written by Herbert Schildt. In particular, you should stay away from C: The Complete Reference, known in some circles as C: The Complete Nonsense.

Also be wary of the book "Let Us C" by Yashwant Kanetkar. It is a horribly outdated book that teaches Turbo C and has lot of obsolete, misleading and downright incorrect material.

Learn C The Hard Way - Zed Shaw. A critique of this book by Tim Hentenaar:

To summarize my views, which are laid out below, the author presents the material in a greatly oversimplified and misleading way, the whole corpus is a bundled mess, and some of the opinions and analyses he offers are just plain wrong. I've tried to view this book through the eyes of a novice, but unfortunately I am biased by years of experience writing code in C. It's obvious to me that either the author has a flawed understanding of C, or he's deliberately oversimplifying to the point where he's actually misleading the reader (intentionally or otherwise.)

"Learn C The Hard Way" is not a book that I could recommend to someone who is both learning to program and learning C. If you're already a competent programmer in some other related language, then it represents an interesting and unusual exposition on C, though I have reservations about parts of the book. Jonathan Leffler


Outdated


Other contributors, not credited in the revision history:
Alex Lockwood, Ben Jackson, Bubbles, claws, coledot, Dana Robinson, Daniel Holden, Dervin Thunk, dwc, Erci Hou, Garen, haziz, Johan Bezem, Jonathan Leffler, Joshua Partogi, Lucas, Lundin, Matt K., mossplix, Matthieu M., midor, Nietzche-jou, Norman Ramsey, r3st0r3, ridthyself, Robert S. Barnes, Tim Ring, Tony Bai, VMAtm

by anonymous   2017-08-20

(I don't know about you but I was excited with assembly)

A simple tool for experimenting with assembly is already installed in your pc.

Go to Start menu->Run, and type debug

debug (command)

debug is a command in DOS, MS-DOS, OS/2 and Microsoft Windows (only x86 versions, not x64) which runs the program debug.exe (or DEBUG.COM in older versions of DOS). Debug can act as an assembler, disassembler, or hex dump program allowing users to interactively examine memory contents (in assembly language, hexadecimal or ASCII), make changes, and selectively execute COM, EXE and other file types. It also has several subcommands which are used to access specific disk sectors, I/O ports and memory addresses. MS-DOS Debug runs at a 16-bit process level and therefore it is limited to 16-bit computer programs. FreeDOS Debug has a "DEBUGX" version supporting 32-bit DPMI programs as well.

Tutorials:

  • A Guide to DEBUG
  • How PC Programs Work: Understanding x86 (Intel) Machine Code
  • DEBUG Tutorial


If you want to understand the code you see in IDA Pro (or OllyDbg), you'll need to learn how compiled code is structured. I recommend the book Reversing: Secrets of Reverse Engineering

I experimented a couple of weeks with debug when I started learning assembly (15 years ago).
Note that debug works at the base machine level, there are no high level assembly commands.

And now a simple example:

Give a to start writing assembly code - type the below program - and finally give g to run it.

alt text


(INT 21 display on screen the ASCII char stored in the DL register if the AH register is set to 2 -- INT 20 terminates the program)

by anonymous   2017-08-20

"In WinDbg I can set breakpoints, but it is difficult for me to imagine at what point to set a breakpoint and at what memory location. Similarly, when I view the static code in IDA Pro, I'm not sure where to even begin to find the function or datastructure that represents the mine field."

Exactly!

Well, you can look for routines like random() that will be called during the construction of the mines table. This book helped me a lot when I was experimenting with reverse engineering. :)

In general, good places for setting break points are calls to message boxes, calls to play a sound, timers and other win32 API routines.

BTW, I am scanning minesweeper right now with OllyDbg.

Update: nemo reminded me a great tool, Cheat Engine by Eric "Dark Byte" Heijnen.

Cheat Engine (CE) is a great tool for watching and modifying other processes memory space. Beyond that basic facility, CE has more special features like viewing the disassembled memory of a process and injecting code into other processes.

(the real value of that project is that you can download the source code -Delphi- and see how those mechanisms were implemented - I did that many years ago :o)

by Simucal   2017-08-20

I've discussed why I don't think Obfuscation is an effective means of protection against cracking here:
Protect .NET Code from reverse engineering

However, your question is specifically about source theft, which is an interesting topic. In Eldad Eiliams book, "Reversing: Secrets of Reverse Engineering", the author discusses source theft as one reason behind reverse engineering in the first two chapters.

Basically, what it comes down to is the only chance you have of being targeted for source theft is if you have some very specific, hard to engineer, algorithm related to your domain that gives you a leg up on your competition. This is just about the only time it would be cost-effective to attempt to reverse engineer a small portion of your application.

So, unless you have some top-secret algorithm you don't want your competition to have, you don't need to worry about source theft. The cost involved with reversing any significant amount of source-code out of your application quickly exceeds the cost of re-writing it from scratch.

Even if you do have some algorithm you don't want them to have, there isn't much you can do to stop determined and skilled individuals from getting it anyway (if the application is executing on their machine).

Some common anti-reversing measures are:

  • Obfuscating - Doesn't do much in terms of protecting your source or preventing it from being cracked. But we might as well not make it totally easy, right?
  • 3rd Party Packers - Themida is one of the better ones. Packs an executable into an encrypted win32 application. Prevents reflection if the application is a .NET app as well.
  • Custom Packers - Sometimes writing your own packer if you have the skill to do so is effective because there is very little information in the cracking scene about how to unpack your application. This can stop inexperienced RE's. This tutorial gives some good information on writing your own packer.
  • Keep industry secret algorithms off the users machine. Execute them as a remove service so the instructions are never executed locally. The only "fool-proof" method of protection.

However, packers can be unpacked, and obfuscation doesn't really hinder those who want to see what you application is doing. If the program is run on the users machine then it is vulnerable.

Eventually its code must be executed as machine code and it is normally a matter of firing up debugger, setting a few breakpoints and monitoring the instructions being executed during the relevant action and some time spent poring over this data.


You mentioned that it took you several months to write ~20kLOC for your application. It would take almost an order of magnitude longer to reverse those equivalent 20kLOC from your application into workable source if you took the bare minimum precautions.

This is why it is only cost-effective to reverse small, industry specific algorithms from your application. Anything else and it isn't worth it.

Take the following fictionalized example: Lets say I just developed a brand new competing application for iTunes that had a ton of bells and whistles. Let say it took several 100k LOC and 2 years to develop. One key feature I have is a new way of serving up music to you based off your music-listening taste.

Apple (being the pirates they are) gets wind of this and decides they really like your music suggest feature so they decide to reverse it. They will then hone-in on only that algorithm and the reverse engineers will eventually come up with a workable algorithm that serves up the equivalent suggestions given the same data. Then they implement said algorithm in their own application, call it "Genius" and make their next 10 trillion dollars.

That is how source theft goes down.

No one would sit there and reverse all 100k LOC to steal significant chunks of your compiled application. It would simply be too costly and too time consuming. About 90% of the time they would be reversing boring, non-industry-secretive code that simply handled button presses or handled user input. Instead, they could hire developers of their own to re-write most of it from scratch for less money and simply reverse the important algorithms that are difficult to engineer and that give you an edge (ie, music suggest feature).

by anonymous   2017-08-20

This is not an easy task and might require tools other than gdb. I read a couple interesting RE tutorials and even though they are not specific to OSX they still provide interesting insight and examples on deciphering function parameters:

Reversing (Undocumented) Windows API Functions

Matt's Cracking Guide

Secrets of Reverse Engineering: Appendix C - Deciphering Program Data

Reverse Engineering and Function Calling by Address

by anonymous   2017-08-20

I like OllyDbg. (with a good companion :)

by anonymous   2017-08-20

That instruction simply pushes 32-bit constant (0x804a254) in the stack.

That instruction alone is not enough for us to tell how it is later used. Could you provide more dissasembly of the code? Especially I would like to see where this value is popped out, and how this value is later being used.

Before starting any reverse engineering I would recommend reading this book (Reverse Engineering secrets) and then X86 instruction set manual (Intel or AMD). I am assuming that you are Reverse Engineering for x86 CPU.