9. Técnicas anti-ingeniería
inversa
DR. MIGUEL ÁNGEL OROS HERNÁNDEZ
Técnicas antiingeniería
inversa
1.
¿Qué es anti-ingeniería inversa?
2. Enfoques
3. Encriptación de código
4. Técnicas anti-depuración
5. Transformaciones de control de
flujo
6. Transformación de datos
¿Qué es anti-ingeniería inversa?
¿Qué es anti-ingeniería inversa?
Regardless of which application
No for open source software
Then, consider introducing some form of
antireversing
Some software development platforms really
necessitate some form of antiversing measures:
bytecode-based platforms such as Java and .NET
Enfoques
Enfoques
Eliminating Symbolic Information
Obfuscating the Program
Eliminate any obvious textual
Generic name for a number of
information from the program
In a regular non-bytecode-based
compiled program, this simply
means to strip all symbolic
information from the program
executable
In bytecode-base programs, the
executables often contain large
amount of internal symbolic
information such as class names,
class member names, and the
names of instantiated global
objects
techniques that are aimed at
reducing the program’s
vulnerability to any kind of static
analysis
Modify the program¿s layout,
logic, data, and organization in a
way that keeps it functionality
identical yer far less readable
¿Qué es anti-ingeniería inversa?
Basic approaches to antireversing
Embedding Antidebugger Code
Idea: have the program intentionally perform
operations that would somehow damage or disable a
debugger, if one is attached
One approach: detect the debugger and terminate
the program
Encriptación de código
Encriptación de código
Common method for
preventing static analysis
Encrypting the program at
some point after it is
compiled
Embedding some sort of
decription code inside the
executable
The program must decrypt
the code in runtime before it
is executed
For the skill full reverser,
there is not an incovenience
Everything required for the
decryption of the program
must reside inside the
executable (decryption logic
and decryption key)
Use ofr unpacker programs
creates a new executable
that contains the original
program minus the
encryption
Encriptación de código
improvements
1.
Try and hide the key within the program
2. Use separate hardware that stores the decryption key or
actually performs the decryption
3. Use a key that is calculated in runtime, inside the
program. Such a key-generation algorithm could easily be
designed that would require a remarkably sophisticaded
unpacker
Técnicas anti-depuración
Técnicas anti-depuración
A large part of the
reversing process often
takes place inside a
debugger
So, incorporate special
code in the program that
prevents or complicates
the process of stepping
through the program and
placing breakpoints in it
Effectiveness of
antidebugger techniques
Antibugger techniques +
code encryption
Allows the program to
decrypt itselt
Transformadores de control de
flujo
Transformaciones de control de flujo
Alter the order and flow of a program in a way that
reduces its human readability
Categories:
Computation transformations
Aggregation transformations
Ordering transformations
Transformaciones de control de flujo
computation transformations
Aimed at reducing the readability of the code by
modifying the program’s original control flow
structure in ways that make for a funcionally
equivant program that is far more difficult to
translate back into a high-level language
How?
Removing control flow information from the program,. Or
Adding new control flow statements that complicate the
program and cannot be easily translated into a high-level
alnguage
Transformaciones de control de flujo
Agregation transformations
Destroy the high-level structure of the program by
breaking the high-level abstractions created by the
programmer while the program was being written
Idea
Break such abstractions so that the high-level organization of
the code becomes senseless
Transformaciones de control de flujo
Ordering transformations
Less powerful transformations
Randomize, as much as possible, the order of
operations in a program so that its readability is
reduced
Transformaciones de control de flujo
Opaque Predicates
Idea: create a logical statement whose outcome is
constant and known in advance
if (x + 1) == x
Is the condition satisfied?
Used to confuse reversers and automated decompilation tools
Objetive: create opaque predicates that would be
difficult to distinguish from the actual program code
and whose behavior would be difficult to predict
without actually stepping into the code
Transformaciones de control de flujo
Confusing Decompilers
There exists decompilers for bytecode executables
Use of obfuscators
confuse decompilers, so the code cannot be easily restored to a
highly detailed source code
One trick: modify the program binary so that the
bytecode contains statements that cannot be
translated back into the original high-level language
Java does not have the goto statment, but Java bytecode does
Transformaciones de control de flujo
Table Interpretation
Converting a program or a function into a table
interpretation layout is a highly powerful obfuscation
approach
Idea
Break a code sequence into multiple short chunks and have the
code loop through a conditional code sequence that decides to
which of the code sequences to jump at any given moment
Reduces the readability of the code because it hides
any kind of structure within it
Transformaciones de control de flujo
Inlining and Outlining
Inlining
A compiler optimization
technique
The functions are
duplicated to any place in
the program that calls them
Instead of having all callers
call into a single copy, the
compiler replaces every call
into the function with an
actual in-place copy of it
Improves runtime
performance
It eliminates the internal
abstractions created by the
software developer
Enhancement
Inlining + Outlining
Transformaciones de control de flujo
Inlining: example
int pred(int x) {
if (x == 0)
return 0;
else
return x - 1;
}
Before inlining:
int f(int y) {
return pred(y) +
pred(0) +
pred(y+1);
}
Transformaciones de control de flujo
Inlining: example
After inlining
int f(int y) {
int temp = 0;
if (y == 0) temp += 0;
else temp += y - 1; /* (1) */
if (0 == 0) temp += 0;
else temp += 0 - 1; /* (2) */
if (y+1 == 0) temp += 0;
else temp += (y + 1) - 1; /* (3) */
return temp;
}
Transformaciones de control de flujo
Inlining and Outlining
Outlining
Means that you take a certain code sequence that
belongs in one function and create a new function
that contains just that sequence
Outlining is opposite of inlining
Transformaciones de control de flujo
Interleaving Code
A reasonably effective obfuscation technique
Idea
You take two or more functiions and interleave their
implementations so that they become exceedingly difficult to
read
Transformaciones de control de flujo
Interleaving Code
Function1()
{
Function1_Segment1;
Function1_Segment2;
Function1_Segment3;
}
Function2()
{
Function2_Segment1;
Function2_Segment2;
Function2_Segment3;
}
Transformaciones de control de flujo
Interleaving Code
Function3()
{
Function3_Segment1;
Function3_Segment2;
Function3_Segment3;
}
Transformaciones de control de flujo
Interleaving Code
Function1_Segment3;
End of Function1
Function1_Segment1; (This is the
Function1 entry-point)
Opaque Predicate -> Always jumps to
Function1_Segment2
Function3_Segment2;
Opaque Predicate -> Always jumps to
Segment3
Transformaciones de control de flujo
Interleaving Code
Function3_Segment1; (This is the Function3
entry-point)
Opaque Predicate -> Always jumps to
Function3_Segment2
Function2_Segment2;
Opaque Predicate -> Always jumps to
Function2_Segment3
Function1_Segment2;
Opaque Predicate -> Always jumps to
Function1_Segment3
Transformaciones de control de flujo
Interleaving Code
Function2_Segment3;
End of Function2
Function3_Segment3;
End of Function3
Function2_Segment1; (This is the
Function2 entry-point)
Opaque Predicate -> Always jumps to
Function2_Segment2
Transformaciones de control de flujo
Ordering Transformations
Shuffling the order of operations in a program is a
free decently effective method for confusing
reversers
Idea
Simply randomize the order of operations in a functioin as
much as possible
Find operations that are not codependent and completely
randomize their order
Transformaciones de datos
Transformaciones de datos
Data transformation are obfuscation transformations
that focus on obfuscating the program’s data rather
the program’s structure
Data transformations also boil down to code
modifications
Transformaciones de datos
Modifying Variable Encoding
Modify the encoding of some or all program
variables
Confuse reversers because the intuitive meaninings
of variable values will not be immediately clear
Example: simply shift it by one bit to the left
For (int i = 1; i < 100; i++)
For (int i = 2; i < 200; i += 2)
Transformaciones de datos
Restructuring Arrays
Means that you modify the layout of some arrays in a
way that preserves their original functionality but
confuses reversers with regard to their purpose
Many different forms to this transformation
Merging more than one array into one large array
Break one array down into several smaller arrays
Change the number of dimensions in an array
Reversing: Secrets of Reverse
Engineering
Bibliografía
Eldad Eilam
Wiley Publishing, Inc.
2005
Fin
© Copyright 2026 Paperzz