SlideShare a Scribd company logo
Obfuscator 
Reloaded 
Johan Wehrli 
Rinaldini Julien
Who the **** are we? 
• Johan Wehrli 
• Master of Science HES-SO in Engineering 
• Scientific Collaborator 
• @jowehrli 
• Julien Rinaldini 
• Master of Science HES-SO in Engineering 
• Research Engineer 
• @pyknite / http://rand0m.ch 
• IICT, Institute for Information an Communication Technology
Evil Plan 
• Obfuscator? 
• LLVM? 
• Tamper-proofing 
• Functions merging 
• Tests 
• Conclusion
Obfuscator 
• Research project in IT security 
• Managed by Phd. Pascal Junod 
• IICT, HEIG-VD 
• Open-source (well, not everything ;) ): http://o-llvm.org 
• Important dates 
• Born in 2010 
• First public release in 2013 
• Still in development 
• Increase software security 
• Substitution, flattening, BCF, …
LLVM 
• Open-source project, written in C++ 
• Compilation framework, several modules 
• Support multiple languages: 
• C/C++, Obj-C, Haskell, Java,… 
• … And multiple architectures: 
• x86, ARM, MIPS, PowerPC,…
Appsec obfuscator reloaded
The tamper-proofing is... 
• Detecting any modifications 
• Making sure that a software is run in the way it 
was expected to be when it was designed
The tamper-proofing is not... 
• A way of preventing the reverse engineering
Two-Step 
• Check 
• Verification of the result 
• Calculation of execution time 
• Hash of a snippet of code 
• Respond 
• Ending the software 
• Restore the initial code 
• Tamper the result or the performance
Typical Attacks 
• Search for patterns 
• Statically 
• Dynamically 
• Deactivation of the RESPOND 
• Modification of the condition 
• Pre-processing the new hash value
Prerequisites - Flattening 
• Flatten the control flow of a function 
• Uses 
• External loop 
• switch 
• One case per basic block 
• Basic block -> end -> switch 
• Branch variable (SwitchVar)
int main(int argc, char **argv){ 
int tab[10] = {5, 9, … , 1}; 
for(int i = 0; i < 10; ++i){ 
printf("%d, ",tab[i]); 
} 
return 0; 
}
Appsec obfuscator reloaded
Now, let’s do some meth math…
Prerequisites - CRC 1/10 
• Linear Code C over a finite field GF(q) of length n 
• C is a cyclic code if, for every word in the code 
• Notions 
• Alphabet : 
• Word : 
• Cyclic code : 
• Generator polynomial : 
• Equations 
c = (c0, c1, ..., cn  1) in GF(q)n 
⇤ = 0, 1 
x = 0b10010 = (1, 0, 0, 1, 0) 2 ⇤5 
00000, 00111, 01110, 01001, 11100, 11011, 10010, 101010 
g(x) = x2 + x + 1 
0 · g(x), 1 · g(x), x · g(x), (x + 1) · g(x), x2 · g(x), (x2 + 1) · g(x), 
(x2 + x) · g(x), (x2 + x + 1) · g(x)
Appsec obfuscator reloaded
Prerequisites - CRC 
• Cyclic Redundancy Check 
• To detect errors during transmission 
• To calculate the remainder of a polynomial division 
• Easy to implement (CRC32) 
• How it works 
• Cyclic code 
• Euclidean division 
• Remainder = CRC
Step One 
• ModulePass, IR code, go through all the 
program 
• …
Appsec obfuscator reloaded
Step One 
• ModulePass, IR code, go through all the 
program 
• Create multiple check functions 
• Pool of functions 
• Random names 
• ...
uint32_t normalCRC(uint32_t init, 
uint32_t* begin, 
uint32_t* end){ 
uint32_t crc = init; 
while(begin  end){ 
__asm__ __volatile__( 
crc32l %%ecx, %%esi; 
:=S (crc) 
:0 (crc), c (*begin) 
); 
++begin; 
} 
return crc; 
} 
uint32_t inverseCRC(uint32_t init, 
uint32_t* begin, 
uint32_t* end){ 
uint32_t crc = init; 
while(begin  end){ 
__asm__ __volatile__( 
crc32l %%ecx, %%esi; 
:=S (crc) 
:0 (crc), c (*end) 
); 
--end; 
} 
return crc; 
}
Step One 
• ModulePass, IR code, go through all the program 
• Create multiple check functions 
• Pool of functions 
• Random names 
• Place random call to the check 
• 1..n per basic block 
• Random area of code 
• ...
... 
store i32 1928457517, i32* %crc, align 4 
store i32* inttoptr (i32 4196792 to i32*), i32** %begin, 
align 8 
store i32* inttoptr (i32 4196848 to i32*), i32** %end, 
align 8 
%2 = load i32* %crc, align 4 
%3 = load i32** %begin, align 8 
%4 = load i32** %end, align 8 
%call = call i32 @vHpAKyNAxHgMhPd(i32 %2, i32* %3, i32* 
%4) 
store i32 %call, i32* %crc, align 4 
...
Step One 
• ModulePass, IR code, go through all the program 
• Create multiple check functions 
• Pool of functions 
• Random names 
• Place random call to the check 
• 1..n per basic block 
• Random area of code 
• Get all the call result, calcul the new SwitchVar 
SwitchV ar = const  res1  res2  ...  resn
... 
%14 = load i32* %const1 
%15 = load i32* %crc, align 4 
%16 = load i32* %crc2, align 4 
%xor = xor i32 %15, %16 
%xor5 = xor i32 %xor, %14 
store i32 %xor5, i32* %switchVar 
...
Appsec obfuscator reloaded
Problems 
• Calculation of the precedence 
• One check area is over the xor 
• Modify the constant value - Modify SwitchVar 
• The pass occurs in the middle-end 
• No addresses 
• No machine code
Solutions 
• Use static array 
• Get the value at a certain address 
• 
SwitchV ar = tab[0]  res1  res2  ...  resn 
• Post-process the binary file 
• Python script 
• PyElfTool
Post-Processing 
• Patch the file once the compilation is over 
• Launch manually 
• Platform dependent 
• Created because the LLVM pass lack informations 
• Begin address 
• End address 
• Hash value 
• Static value
Post-Processing 
• Read the log file 
• Find the data 
• Heuristic vs. Search 
• Search by function 
• Update the data 
• Calculate the offset 
• Update the addresses 
• Calculate the check 
• Update the static value
Conclusion - Tamper 
• Selection policies 
• Area : .Text vs. Function 
• CHECK placement 
• Control flow modification 
• Good combinaison between static and dynamic values 
• Future 
• Use the Clang driver, detect link phase 
• Generic solution, uses the LLVM API
Functions Merging 
What is that?
// Module test.c 
int foo(int a) { 
return a+2; 
} 
float bar(float a) { 
return a+2.0; 
}
// Module test.c 
void merge(int sw, void *ret, ...) { 
switch(sw) { 
case 0: 
va_list ap; 
va_start(ap, 1); 
int a = va_args(ap, int); 
va_end(ap); 
int *b = (int*)ret; 
*b = a+2; 
break; 
case 1: 
va_list ap; 
va_start(ap, 1); 
float a = va_args(ap, float); 
va_end(ap); 
float *b = (float*)ret; 
*b = a+2.0; 
break; 
} 
return; 
}
input: Module M 
begin 
fList ;; 
foreach function f in module M do 
if f is not a declaration and f is not main then 
fList fList[ {f}; 
end 
end 
merge createFunction(); 
foreach function f in fList do 
addEntryToSwitch(f,merge); 
if f has arguments then 
loadArgs(f,merge); 
end 
replaceReturn(f,merge); 
moveContent(f,merge); 
createWrapper(f,M); 
end 
end
input: Module M 
begin 
fList ;; 
foreach function f in module M do 
if f is not a declaration and f is not main then 
fList fList[ {f}; 
end 
end 
merge createFunction(); 
foreach function f in fList do 
addEntryToSwitch(f,merge); 
if f has arguments then 
loadArgs(f,merge); 
end 
replaceReturn(f,merge); 
moveContent(f,merge); 
createWrapper(f,M); 
end 
end
• Save all functions, except: 
• main() 
• Arbitrary choice 
• Variadic functions 
• Special treatment needed 
• No time left to implement it 
• fastcall functions 
• Try to pass arguments through registers
input: Module M 
begin 
fList ;; 
foreach function f in module M do 
if f is not a declaration and f is not main then 
fList fList[ {f}; 
end 
end 
merge createFunction(); 
foreach function f in fList do 
addEntryToSwitch(f,merge); 
if f has arguments then 
loadArgs(f,merge); 
end 
replaceReturn(f,merge); 
moveContent(f,merge); 
createWrapper(f,M); 
end 
end
• Merge function 
• 3 arguments 
• int sw 
• void *result 
• variadic argument (…) 
• Uses a switch as a dispatcher 
• Random name - avoid linking problems 
define void @merge-1196957890(i128 %sw, i8* %retArg, ...) { 
entry: 
%sw.addr = alloca i128 
store i128 %sw, i128* %sw.addr 
%sw1 = load i128* %sw.addr 
switch i128 %sw1, label %default [ 
] 
default: ; preds = %entry 
ret void 
}
input: Module M 
begin 
fList ;; 
foreach function f in module M do 
if f is not a declaration and f is not main then 
fList fList[ {f}; 
end 
end 
merge createFunction(); 
foreach function f in fList do 
addEntryToSwitch(f,merge); 
if f has arguments then 
loadArgs(f,merge); 
end 
replaceReturn(f,merge); 
moveContent(f,merge); 
createWrapper(f,M); 
end 
end
• switch value 
• sha256 + salt 
• Only use 128 bits 
• Avoid online attack 
switch i128 %sw1, label %default [ 
i128 27710209634873760713303062182632130818 , label %0 
i128 -6843076191789525760054781676266687358 , label %17 
i128 -26221607966511614330399007306620848255 , label %56 
]
input: Module M 
begin 
fList ;; 
foreach function f in module M do 
if f is not a declaration and f is not main then 
fList fList[ {f}; 
end 
end 
merge createFunction(); 
foreach function f in fList do 
addEntryToSwitch(f,merge); 
if f has arguments then 
loadArgs(f,merge); 
end 
replaceReturn(f,merge); 
moveContent(f,merge); 
createWrapper(f,M); 
end 
end
... 
%ap = alloca i8* 
%ap2 = bitcast i8** %ap to i8* 
call void @llvm.va_start(i8* %ap2) 
%1 = va_arg i8** %ap, i32 
call void @llvm.va_end(i8* %ap2) 
...
input: Module M 
begin 
fList ;; 
foreach function f in module M do 
if f is not a declaration and f is not main then 
fList fList[ {f}; 
end 
end 
merge createFunction(); 
foreach function f in fList do 
addEntryToSwitch(f,merge); 
if f has arguments then 
loadArgs(f,merge); 
end 
replaceReturn(f,merge); 
moveContent(f,merge); 
createWrapper(f,M); 
end 
end
• Replace all return 
• load the return value in the retArg 
• ret void 
... 
%14 = alloca i8* 
store i8* %retArg , i8** %14 
%15 = load i8** %14 
%16 = bitcast i8* %15 to i32* 
store i32 3, i32* %16 
ret void
• We still have some problems 
• Inter-module calls 
• Distribution of an obfuscated library 
• API breakage
• Wrappers! The solution for every problems ;) 
; Function Attrs: nounwind ssp uwtable 
define float @bar(float %a) { 
entry: 
%ret = alloca float 
%retPty = alloca float* 
store float* %ret, float** %retPty 
%load = load float** %retPty 
%bit = bitcast float* %load to i8* 
call void (i128, i8*, ...)* @merge1806660435(i128 
49770522224456207387965548547940082999, i8* %bit, float %a) 
%0 = load float** %retPty 
%1 = load float* %0 
ret float %1 
}
Conclusion - Function 
merging 
• Use strip! 
• Fonctions name give a lot of informations 
• Use it with other obfuscations
Tests 
• Test suite 
• LibTomCrypt 
• OpenSSL 
• SQLite (+200’000 tests) 
• Obfuscation of ALL the code 
• Global idea of the consequences
Conclusion 
• Both obfuscations works fine 
• Debugging is hard 
• Promising project 
• A lot of others obfuscations 
• Flattening V2, debug tricks, tamper V2,… 
• Backend obfuscations 
• Winner “Bourse Start-Up Heig-VD 2014”
▄▄▄▄▄▄▄▄▄▄ 
▄▄█████████▄▄▄▄▄ 
██▄▄▄██████▄▄▄██▄▄ 
██▄▄▄██████▄████████ 
▄██▄████▄▄▄▄▄▄▄▄▄████ 
████████████████▄▄███ 
██████▄▄▄▄▄▄█████▄▄▄▄ 
▀█████▄▄███████▄▄▄█▄▀ 
Questions? 
▄▄▄▄▄▄▄▄▄ ████▄████████▄▄▄▀ 
▄▄█████████▄▄ ▄▄██████████▄███ 
███████▄▀▀▀▄█▄▄ ▄▄▄█▄▄█▄▄█▄▄▄▄▄▀▀ 
████████ ▀▄▄▄▄███▄██▄▄▄███ 
████████ ▄▄ ▄▄▄▄▄█▄▄▄▄███████ 
████████▄▄██ ██▄▄▄██████████▄▀ 
▀▄██████▄▄▄▀ ▀▄█▄██████████▄▀ 
▄▄████▄▄██ ▄███▄█▄▄▄▄██▄██ 
█████████▄▀ █████▄▄▀ ██████ 
███▄███▀▀ ███████ ███▄▄▄▄ 
▀▄▄▄▀ ████████ ███████ 
████████ ████▄▄██▄ 
██████▄▄█ ██████▄▄█ 
█▄▄▄▄█ █▄▄▄▄█

More Related Content

PDF
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
PDF
Digital system design practical file
PDF
Vhdl lab manual
PDF
Dsd lab Practical File
PDF
Introduction to Erlang Part 2
PDF
Introduction to Erlang Part 1
PDF
Programs of VHDL
PDF
Experiment write-vhdl-code-for-realize-all-logic-gates
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
Digital system design practical file
Vhdl lab manual
Dsd lab Practical File
Introduction to Erlang Part 2
Introduction to Erlang Part 1
Programs of VHDL
Experiment write-vhdl-code-for-realize-all-logic-gates

What's hot (19)

DOCX
VERILOG CODE
PPT
Verilog Lecture3 hust 2014
DOC
VLSI Anna University Practical Examination
DOCX
radix_4 fft dif with mdc and mdf
PPT
Verilog Lecture4 2014
PPTX
Triton and Symbolic execution on GDB@DEF CON China
PDF
Lecture 2 verilog
PDF
VLSI Lab manual PDF
PDF
Dynamic Binary Analysis and Obfuscated Codes
PPT
Verilog Lecture5 hust 2014
PPT
Fpga 06-data-types-system-tasks-compiler-directives
DOCX
verilog code
PDF
Address/Thread/Memory Sanitizer
PPTX
CSharp for Unity Day2
PDF
Klee and angr
PPT
Verilog Lecture2 thhts
PPT
Verilogforlab
PPTX
An introduction to ROP
PDF
Day2 Verilog HDL Basic
VERILOG CODE
Verilog Lecture3 hust 2014
VLSI Anna University Practical Examination
radix_4 fft dif with mdc and mdf
Verilog Lecture4 2014
Triton and Symbolic execution on GDB@DEF CON China
Lecture 2 verilog
VLSI Lab manual PDF
Dynamic Binary Analysis and Obfuscated Codes
Verilog Lecture5 hust 2014
Fpga 06-data-types-system-tasks-compiler-directives
verilog code
Address/Thread/Memory Sanitizer
CSharp for Unity Day2
Klee and angr
Verilog Lecture2 thhts
Verilogforlab
An introduction to ROP
Day2 Verilog HDL Basic
Ad

Similar to Appsec obfuscator reloaded (20)

PPT
443600107-1-Introduction-to education -C-ppt
PPT
443600107-1-Introduction-to-C-ppt (1).ppt
PDF
Lecture07(DHDNBK)-Behavior-Modelling.pdf
PPT
02 functions, variables, basic input and output of c++
PDF
Memory Management with Java and C++
PDF
openMP loop parallelization
PPT
Lecture#6 functions in c++
PDF
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
PPTX
functions
PPTX
C++ Functions
PDF
Practical file
PDF
Actor Concurrency
PDF
Cse115 lecture04introtoc programming
PDF
掀起 Swift 的面紗
PPTX
Object oriented programming system with C++
PPTX
golang_getting_started.pptx
PPTX
Getting started cpp full
PDF
Golang and Eco-System Introduction / Overview
443600107-1-Introduction-to education -C-ppt
443600107-1-Introduction-to-C-ppt (1).ppt
Lecture07(DHDNBK)-Behavior-Modelling.pdf
02 functions, variables, basic input and output of c++
Memory Management with Java and C++
openMP loop parallelization
Lecture#6 functions in c++
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
functions
C++ Functions
Practical file
Actor Concurrency
Cse115 lecture04introtoc programming
掀起 Swift 的面紗
Object oriented programming system with C++
golang_getting_started.pptx
Getting started cpp full
Golang and Eco-System Introduction / Overview
Ad

More from Cyber Security Alliance (20)

PDF
Bug Bounty @ Swisscom
PDF
Robots are among us, but who takes responsibility?
PDF
iOS malware: what's the risk and how to reduce it
PDF
Why huntung IoC fails at protecting against targeted attacks
PDF
Corporations - the new victims of targeted ransomware
PDF
Blockchain for Beginners
PDF
Le pentest pour les nuls #cybsec16
PDF
Introducing Man in the Contacts attack to trick encrypted messaging apps
PDF
Understanding the fundamentals of attacks
PDF
Rump : iOS patch diffing
PDF
An easy way into your sap systems v3.0
PDF
Reverse engineering Swisscom's Centro Grande Modem
PDF
Easy public-private-keys-strong-authentication-using-u2 f
PDF
Create a-strong-two-factors-authentication-device-for-less-than-chf-100
PDF
Offline bruteforce attack on wi fi protected setup
PDF
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
PPTX
Warning Ahead: SecurityStorms are Brewing in Your JavaScript
PDF
Killing any security product … using a Mimikatz undocumented feature
PDF
Rump attaque usb_caralinda_fabrice
PDF
Operation emmental appsec
Bug Bounty @ Swisscom
Robots are among us, but who takes responsibility?
iOS malware: what's the risk and how to reduce it
Why huntung IoC fails at protecting against targeted attacks
Corporations - the new victims of targeted ransomware
Blockchain for Beginners
Le pentest pour les nuls #cybsec16
Introducing Man in the Contacts attack to trick encrypted messaging apps
Understanding the fundamentals of attacks
Rump : iOS patch diffing
An easy way into your sap systems v3.0
Reverse engineering Swisscom's Centro Grande Modem
Easy public-private-keys-strong-authentication-using-u2 f
Create a-strong-two-factors-authentication-device-for-less-than-chf-100
Offline bruteforce attack on wi fi protected setup
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
Warning Ahead: SecurityStorms are Brewing in Your JavaScript
Killing any security product … using a Mimikatz undocumented feature
Rump attaque usb_caralinda_fabrice
Operation emmental appsec

Recently uploaded (20)

PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
OMC Textile Division Presentation 2021.pptx
PPTX
Spectroscopy.pptx food analysis technology
PDF
August Patch Tuesday
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Machine Learning_overview_presentation.pptx
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Approach and Philosophy of On baking technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Unlocking AI with Model Context Protocol (MCP)
OMC Textile Division Presentation 2021.pptx
Spectroscopy.pptx food analysis technology
August Patch Tuesday
Network Security Unit 5.pdf for BCA BBA.
Advanced methodologies resolving dimensionality complications for autism neur...
Mobile App Security Testing_ A Comprehensive Guide.pdf
NewMind AI Weekly Chronicles - August'25-Week II
Univ-Connecticut-ChatGPT-Presentaion.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Machine Learning_overview_presentation.pptx
Assigned Numbers - 2025 - Bluetooth® Document
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Approach and Philosophy of On baking technology
Reach Out and Touch Someone: Haptics and Empathic Computing
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Heart disease approach using modified random forest and particle swarm optimi...
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Digital-Transformation-Roadmap-for-Companies.pptx

Appsec obfuscator reloaded

  • 1. Obfuscator Reloaded Johan Wehrli Rinaldini Julien
  • 2. Who the **** are we? • Johan Wehrli • Master of Science HES-SO in Engineering • Scientific Collaborator • @jowehrli • Julien Rinaldini • Master of Science HES-SO in Engineering • Research Engineer • @pyknite / http://rand0m.ch • IICT, Institute for Information an Communication Technology
  • 3. Evil Plan • Obfuscator? • LLVM? • Tamper-proofing • Functions merging • Tests • Conclusion
  • 4. Obfuscator • Research project in IT security • Managed by Phd. Pascal Junod • IICT, HEIG-VD • Open-source (well, not everything ;) ): http://o-llvm.org • Important dates • Born in 2010 • First public release in 2013 • Still in development • Increase software security • Substitution, flattening, BCF, …
  • 5. LLVM • Open-source project, written in C++ • Compilation framework, several modules • Support multiple languages: • C/C++, Obj-C, Haskell, Java,… • … And multiple architectures: • x86, ARM, MIPS, PowerPC,…
  • 7. The tamper-proofing is... • Detecting any modifications • Making sure that a software is run in the way it was expected to be when it was designed
  • 8. The tamper-proofing is not... • A way of preventing the reverse engineering
  • 9. Two-Step • Check • Verification of the result • Calculation of execution time • Hash of a snippet of code • Respond • Ending the software • Restore the initial code • Tamper the result or the performance
  • 10. Typical Attacks • Search for patterns • Statically • Dynamically • Deactivation of the RESPOND • Modification of the condition • Pre-processing the new hash value
  • 11. Prerequisites - Flattening • Flatten the control flow of a function • Uses • External loop • switch • One case per basic block • Basic block -> end -> switch • Branch variable (SwitchVar)
  • 12. int main(int argc, char **argv){ int tab[10] = {5, 9, … , 1}; for(int i = 0; i < 10; ++i){ printf("%d, ",tab[i]); } return 0; }
  • 14. Now, let’s do some meth math…
  • 15. Prerequisites - CRC 1/10 • Linear Code C over a finite field GF(q) of length n • C is a cyclic code if, for every word in the code • Notions • Alphabet : • Word : • Cyclic code : • Generator polynomial : • Equations c = (c0, c1, ..., cn 1) in GF(q)n ⇤ = 0, 1 x = 0b10010 = (1, 0, 0, 1, 0) 2 ⇤5 00000, 00111, 01110, 01001, 11100, 11011, 10010, 101010 g(x) = x2 + x + 1 0 · g(x), 1 · g(x), x · g(x), (x + 1) · g(x), x2 · g(x), (x2 + 1) · g(x), (x2 + x) · g(x), (x2 + x + 1) · g(x)
  • 17. Prerequisites - CRC • Cyclic Redundancy Check • To detect errors during transmission • To calculate the remainder of a polynomial division • Easy to implement (CRC32) • How it works • Cyclic code • Euclidean division • Remainder = CRC
  • 18. Step One • ModulePass, IR code, go through all the program • …
  • 20. Step One • ModulePass, IR code, go through all the program • Create multiple check functions • Pool of functions • Random names • ...
  • 21. uint32_t normalCRC(uint32_t init, uint32_t* begin, uint32_t* end){ uint32_t crc = init; while(begin end){ __asm__ __volatile__( crc32l %%ecx, %%esi; :=S (crc) :0 (crc), c (*begin) ); ++begin; } return crc; } uint32_t inverseCRC(uint32_t init, uint32_t* begin, uint32_t* end){ uint32_t crc = init; while(begin end){ __asm__ __volatile__( crc32l %%ecx, %%esi; :=S (crc) :0 (crc), c (*end) ); --end; } return crc; }
  • 22. Step One • ModulePass, IR code, go through all the program • Create multiple check functions • Pool of functions • Random names • Place random call to the check • 1..n per basic block • Random area of code • ...
  • 23. ... store i32 1928457517, i32* %crc, align 4 store i32* inttoptr (i32 4196792 to i32*), i32** %begin, align 8 store i32* inttoptr (i32 4196848 to i32*), i32** %end, align 8 %2 = load i32* %crc, align 4 %3 = load i32** %begin, align 8 %4 = load i32** %end, align 8 %call = call i32 @vHpAKyNAxHgMhPd(i32 %2, i32* %3, i32* %4) store i32 %call, i32* %crc, align 4 ...
  • 24. Step One • ModulePass, IR code, go through all the program • Create multiple check functions • Pool of functions • Random names • Place random call to the check • 1..n per basic block • Random area of code • Get all the call result, calcul the new SwitchVar SwitchV ar = const res1 res2 ... resn
  • 25. ... %14 = load i32* %const1 %15 = load i32* %crc, align 4 %16 = load i32* %crc2, align 4 %xor = xor i32 %15, %16 %xor5 = xor i32 %xor, %14 store i32 %xor5, i32* %switchVar ...
  • 27. Problems • Calculation of the precedence • One check area is over the xor • Modify the constant value - Modify SwitchVar • The pass occurs in the middle-end • No addresses • No machine code
  • 28. Solutions • Use static array • Get the value at a certain address • SwitchV ar = tab[0] res1 res2 ... resn • Post-process the binary file • Python script • PyElfTool
  • 29. Post-Processing • Patch the file once the compilation is over • Launch manually • Platform dependent • Created because the LLVM pass lack informations • Begin address • End address • Hash value • Static value
  • 30. Post-Processing • Read the log file • Find the data • Heuristic vs. Search • Search by function • Update the data • Calculate the offset • Update the addresses • Calculate the check • Update the static value
  • 31. Conclusion - Tamper • Selection policies • Area : .Text vs. Function • CHECK placement • Control flow modification • Good combinaison between static and dynamic values • Future • Use the Clang driver, detect link phase • Generic solution, uses the LLVM API
  • 33. // Module test.c int foo(int a) { return a+2; } float bar(float a) { return a+2.0; }
  • 34. // Module test.c void merge(int sw, void *ret, ...) { switch(sw) { case 0: va_list ap; va_start(ap, 1); int a = va_args(ap, int); va_end(ap); int *b = (int*)ret; *b = a+2; break; case 1: va_list ap; va_start(ap, 1); float a = va_args(ap, float); va_end(ap); float *b = (float*)ret; *b = a+2.0; break; } return; }
  • 35. input: Module M begin fList ;; foreach function f in module M do if f is not a declaration and f is not main then fList fList[ {f}; end end merge createFunction(); foreach function f in fList do addEntryToSwitch(f,merge); if f has arguments then loadArgs(f,merge); end replaceReturn(f,merge); moveContent(f,merge); createWrapper(f,M); end end
  • 36. input: Module M begin fList ;; foreach function f in module M do if f is not a declaration and f is not main then fList fList[ {f}; end end merge createFunction(); foreach function f in fList do addEntryToSwitch(f,merge); if f has arguments then loadArgs(f,merge); end replaceReturn(f,merge); moveContent(f,merge); createWrapper(f,M); end end
  • 37. • Save all functions, except: • main() • Arbitrary choice • Variadic functions • Special treatment needed • No time left to implement it • fastcall functions • Try to pass arguments through registers
  • 38. input: Module M begin fList ;; foreach function f in module M do if f is not a declaration and f is not main then fList fList[ {f}; end end merge createFunction(); foreach function f in fList do addEntryToSwitch(f,merge); if f has arguments then loadArgs(f,merge); end replaceReturn(f,merge); moveContent(f,merge); createWrapper(f,M); end end
  • 39. • Merge function • 3 arguments • int sw • void *result • variadic argument (…) • Uses a switch as a dispatcher • Random name - avoid linking problems define void @merge-1196957890(i128 %sw, i8* %retArg, ...) { entry: %sw.addr = alloca i128 store i128 %sw, i128* %sw.addr %sw1 = load i128* %sw.addr switch i128 %sw1, label %default [ ] default: ; preds = %entry ret void }
  • 40. input: Module M begin fList ;; foreach function f in module M do if f is not a declaration and f is not main then fList fList[ {f}; end end merge createFunction(); foreach function f in fList do addEntryToSwitch(f,merge); if f has arguments then loadArgs(f,merge); end replaceReturn(f,merge); moveContent(f,merge); createWrapper(f,M); end end
  • 41. • switch value • sha256 + salt • Only use 128 bits • Avoid online attack switch i128 %sw1, label %default [ i128 27710209634873760713303062182632130818 , label %0 i128 -6843076191789525760054781676266687358 , label %17 i128 -26221607966511614330399007306620848255 , label %56 ]
  • 42. input: Module M begin fList ;; foreach function f in module M do if f is not a declaration and f is not main then fList fList[ {f}; end end merge createFunction(); foreach function f in fList do addEntryToSwitch(f,merge); if f has arguments then loadArgs(f,merge); end replaceReturn(f,merge); moveContent(f,merge); createWrapper(f,M); end end
  • 43. ... %ap = alloca i8* %ap2 = bitcast i8** %ap to i8* call void @llvm.va_start(i8* %ap2) %1 = va_arg i8** %ap, i32 call void @llvm.va_end(i8* %ap2) ...
  • 44. input: Module M begin fList ;; foreach function f in module M do if f is not a declaration and f is not main then fList fList[ {f}; end end merge createFunction(); foreach function f in fList do addEntryToSwitch(f,merge); if f has arguments then loadArgs(f,merge); end replaceReturn(f,merge); moveContent(f,merge); createWrapper(f,M); end end
  • 45. • Replace all return • load the return value in the retArg • ret void ... %14 = alloca i8* store i8* %retArg , i8** %14 %15 = load i8** %14 %16 = bitcast i8* %15 to i32* store i32 3, i32* %16 ret void
  • 46. • We still have some problems • Inter-module calls • Distribution of an obfuscated library • API breakage
  • 47. • Wrappers! The solution for every problems ;) ; Function Attrs: nounwind ssp uwtable define float @bar(float %a) { entry: %ret = alloca float %retPty = alloca float* store float* %ret, float** %retPty %load = load float** %retPty %bit = bitcast float* %load to i8* call void (i128, i8*, ...)* @merge1806660435(i128 49770522224456207387965548547940082999, i8* %bit, float %a) %0 = load float** %retPty %1 = load float* %0 ret float %1 }
  • 48. Conclusion - Function merging • Use strip! • Fonctions name give a lot of informations • Use it with other obfuscations
  • 49. Tests • Test suite • LibTomCrypt • OpenSSL • SQLite (+200’000 tests) • Obfuscation of ALL the code • Global idea of the consequences
  • 50. Conclusion • Both obfuscations works fine • Debugging is hard • Promising project • A lot of others obfuscations • Flattening V2, debug tricks, tamper V2,… • Backend obfuscations • Winner “Bourse Start-Up Heig-VD 2014”
  • 51. ▄▄▄▄▄▄▄▄▄▄ ▄▄█████████▄▄▄▄▄ ██▄▄▄██████▄▄▄██▄▄ ██▄▄▄██████▄████████ ▄██▄████▄▄▄▄▄▄▄▄▄████ ████████████████▄▄███ ██████▄▄▄▄▄▄█████▄▄▄▄ ▀█████▄▄███████▄▄▄█▄▀ Questions? ▄▄▄▄▄▄▄▄▄ ████▄████████▄▄▄▀ ▄▄█████████▄▄ ▄▄██████████▄███ ███████▄▀▀▀▄█▄▄ ▄▄▄█▄▄█▄▄█▄▄▄▄▄▀▀ ████████ ▀▄▄▄▄███▄██▄▄▄███ ████████ ▄▄ ▄▄▄▄▄█▄▄▄▄███████ ████████▄▄██ ██▄▄▄██████████▄▀ ▀▄██████▄▄▄▀ ▀▄█▄██████████▄▀ ▄▄████▄▄██ ▄███▄█▄▄▄▄██▄██ █████████▄▀ █████▄▄▀ ██████ ███▄███▀▀ ███████ ███▄▄▄▄ ▀▄▄▄▀ ████████ ███████ ████████ ████▄▄██▄ ██████▄▄█ ██████▄▄█ █▄▄▄▄█ █▄▄▄▄█