爲了不被0xd4d(de4dot做者)認爲是"N00bUser"
爲了認識到Some of the advanced options may be incompatible, causing a nice exception.
With great power comes great responsibility.(de4dot開頭2句話,可google翻譯)
務必要了解如何帶參數運行de4dot!!!
php
「de4dot彈出的用法都是英文,我看不懂怎麼辦?」
因此我寫了一篇入門級教程,只要能認真看此貼,多用de4dot脫複雜些的殼,你必定能掌握de4dot的高級用法
html
在此以前,你須要準備好:
1. dnSpy(勾好這個選項)
<ignore_js_op>
2. de4dot(最新版請點擊https://ci.appveyor.com/project/0xd4d/de4dot/branch/master/artifacts下載)
git
直接運行de4dot,看看de4dot告訴咱們如何使用它。
這裏我直接把英文以及翻譯附上。會提到的參數標記爲紅色,這些比較經常使用
github
de4dot v3.1.41592.3405 Copyright (C) 2011-2015 de4dot@gmail.com
Latest version and source code: https://github.com/0xd4d/de4dot
Some of the advanced options may be incompatible, causing a nice exception.
With great power comes great responsibility.
de4dot.exe <options> <file options>
Options:
//全局參數
-r DIR Scan for .NET files in all subdirs
//搜索當前目錄以及子目錄中全部程序集並去混淆
-ro DIR Output base dir for recursively found files
//同-r參數,可是並不搜索子目錄,僅限當前目錄
-ru Skip recursively found files with unsupported obfuscator
//跳過查找到帶有de4dot不支持的混淆器的程序集
-d Detect obfuscators and exit
//查明混淆器名稱,而後退出de4dot
--asm-path PATH Add an assembly search path
//增長一個被搜索的目錄
--dont-rename Don't rename classes, methods, etc.
//禁止全部重命名(好比類,方法,字段,屬性,資源......)
--keep-names FLAGS
Don't rename n(amespaces), t(ypes), p(rops), e(vents), f(ields), m(ethods), a(rgs), g(enericparams), d(elegate fields). Can be combined, eg. efm
//禁止對指定內容重命名。好比我不想重命名命名空間、類名和方法名,那麼我能夠添加這樣一個參數"--keep-names ntm",這裏的n表明namespaces,t表明types,m表明methods
--dont-create-params
Don't create method params when renaming
//在重命名時不建立方法參數(?我也看不太懂)
--dont-restore-props
Don't restore properties/events
//不還原屬性和事件
--default-strtyp TYPE
Default string decrypter type
//與--strtyp相似
--default-strtok METHOD
Default string decrypter method token or [type::][name][(args,...)]
//與--strtok相似
--no-cflow-deob No control flow deobfuscation (NOT recommended)
//不還原控制流混淆(舉個例子,ConfuserEx的恐怖的switch,幾乎只能讓程序來還原)
--only-cflow-deob
Only control flow deobfuscation
//僅還原控制流混淆
--load-new-process
Load executed assemblies into a new process
//將程序集放在新進程中進行脫殼處理
--keep-types Keep obfuscator types, fields, methods
//保留混淆器類、字段和方法
--preserve-tokens
Preserve important tokens, #US, #Blob, extra sig data
//保持tokens不變,包括#US, #Blob, extra sig data。好比有個方法的token是0x06000008,不使用這個選項,去混淆以後某方法的token可能會變成0x06000004(好比這以前有4個無效方法被de4dot移除了),使用這個選項以後,不管怎樣,方法的token始終是0x06000008
--preserve-table FLAGS
Preserve rids in table: tr (TypeRef), td (TypeDef), fd (Field), md (Method), pd (Param), mr (MemberRef), s (StandAloneSig), ed (Event), pr (Property), ts (TypeSpec), ms (MethodSpec), all (all previous tables). Use - to disable (eg. all,-pd). Can be combined: ed,fd,md
//保持表中指定種類的tokens不變。好比"--preserve-table ed,fd,md","--preserve-table all"
--preserve-strings
Preserve #Strings heap offsets
//保持#Strings堆偏移不變
--preserve-us Preserve #US heap offsets
//保持#US堆偏移不變
--preserve-blob Preserve #Blob heap offsets
//保持#Blob堆偏移不變
--preserve-sig-data
Preserve extra data at the end of signatures
//保持額外的簽名數據偏移不變
--one-file Deobfuscate one file at a time
//一次只對一個程序集去混淆
-v Verbose
//顯示詳細信息
-vv Very verbose
//顯示更多詳細信息(?應該是,反正和-v同樣都會顯示信息)
-h Show this help message
//顯示幫助,就是我翻譯的這些內容
--help Same as -h
//同-h
File options:
//局部參數
-f FILE Name of .NET file
//指定被去混淆的程序集的路徑(能夠是相對路徑或者絕對路徑)
-o FILE Name of output file
//指定輸出去混淆後的程序集的路徑(能夠是相對路徑或者絕對路徑)
-p TYPE Obfuscator type (see below)
//指定混淆器類型(下面寫了)
--strtyp TYPE String decrypter type
//指定如何使用字符串解密器(字符串解密器指的是被混淆程序集中的一個方法)
--strtok METHOD String decrypter method token or [type::][name][(args,...)]
//指定哪個方法做爲字符串解密器
Deobfuscator options:
//混淆器參數(我就不翻譯了,由於有些沒用過,不是很經常使用)
//好比"--un-name REGEX Valid name regex pattern (^[a-zA-Z_<{$][a-zA-Z_0-9<>{}$.`-]*$)"
//全大寫單詞表明一個參數,最尾處有一個括號,裏面表明默認參數,若是你不填這個參數,那麼de4dot認爲你輸入了--un-name "^[a-zA-Z_<{$][a-zA-Z_0-9<>{}$.`-]*$",由於這是默認的
//這裏有個地方要注意,REGEX的內容必定要用""包起來,好比--un-name ^就是無效的,--un-name "^ "是有效的
//而BOOL只要直接輸入True/False,好比--an-methods True
Type un (Unknown)
--un-name REGEX Valid name regex pattern (^[a-zA-Z_<{$][a-zA-Z_0-9<>{}$.`-]*$)
Type an (Agile.NET)
--an-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--an-methods BOOL
Decrypt methods (True)
--an-rsrc BOOL Decrypt resources (True)
--an-stack BOOL Remove all StackFrameHelper code (True)
--an-vm BOOL Restore VM code (True)
--an-initlocals BOOL
Set initlocals in method header (True)
Type bl (Babel .NET)
--bl-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--bl-inline BOOL Inline short methods (True)
--bl-remove-inlined BOOL
Remove inlined methods (True)
--bl-methods BOOL
Decrypt methods (True)
--bl-rsrc BOOL Decrypt resources (True)
--bl-consts BOOL Decrypt constants and arrays (True)
--bl-embedded BOOL
Dump embedded assemblies (True)
Type cf (CodeFort)
--cf-name REGEX Valid name regex pattern (!^[a-zA-Z]{1,3}$&!^[_<>{}$.`-]$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--cf-embedded BOOL
Dump embedded assemblies (True)
Type cv (CodeVeil)
--cv-name REGEX Valid name regex pattern (!^[A-Za-z]{1,2}$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
Type cw (CodeWall)
--cw-name REGEX Valid name regex pattern (!^[0-9A-F]{32}$&!^[_<>{}$.`-]$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--cw-embedded BOOL
Dump embedded assemblies (True)
--cw-decrypt-main BOOL
Decrypt main embedded assembly (True)
Type cr (Confuser)
--cr-name REGEX Valid name regex pattern (^[a-zA-Z_<{$][a-zA-Z_0-9<>{}$.`-]*$)
--cr-antidb BOOL Remove anti debug code (True)
--cr-antidump BOOL
Remove anti dump code (True)
--cr-decrypt-main BOOL
Decrypt main embedded assembly (True)
Type co (Crypto Obfuscator)
--co-name REGEX Valid name regex pattern (!^(get_|set_|add_|remove_)?[A-Z]{1,3}(?:`\d+)?$&!^(get_|set_|add_|remove_)?c[0-9a-f]{32}(?:`\d+)?$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--co-tamper BOOL Remove tamper protection code (True)
--co-consts BOOL Decrypt constants (True)
--co-inline BOOL Inline short methods (True)
--co-ldnull BOOL Restore ldnull instructions (True)
Type ds (DeepSea)
--ds-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--ds-inline BOOL Inline short methods (True)
--ds-remove-inlined BOOL
Remove inlined methods (True)
--ds-rsrc BOOL Decrypt resources (True)
--ds-embedded BOOL
Dump embedded assemblies (True)
--ds-fields BOOL Restore fields (True)
--ds-keys BOOL Rename resource keys (True)
--ds-casts BOOL Deobfuscate casts (True)
Type df (Dotfuscator)
--df-name REGEX Valid name regex pattern (!^(?:eval_)?[a-z][a-z0-9]{0,2}$&!^A_[0-9]+$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
Type dr3 (.NET Reactor)
--dr3-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--dr3-types BOOL Restore types (object -> real type) (True)
--dr3-inline BOOL
Inline short methods (True)
--dr3-remove-inlined BOOL
Remove inlined methods (True)
--dr3-ns1 BOOL Clear namespace if there's only one class in it (True)
--dr3-sn BOOL Remove anti strong name code (True)
Type dr4 (.NET Reactor)
--dr4-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--dr4-methods BOOL
Decrypt methods (True)
--dr4-bools BOOL Decrypt booleans (True)
--dr4-types BOOL Restore types (object -> real type) (True)
--dr4-inline BOOL
Inline short methods (True)
--dr4-remove-inlined BOOL
Remove inlined methods (True)
--dr4-embedded BOOL
Dump embedded assemblies (True)
--dr4-rsrc BOOL Decrypt resources (True)
--dr4-ns1 BOOL Clear namespace if there's only one class in it (True)
--dr4-sn BOOL Remove anti strong name code (True)
--dr4-sname BOOL Rename short names (False)
Type ef (Eazfuscator.NET)
--ef-name REGEX Valid name regex pattern (!^[a-zA-Z]$&!^#=&!^dje_.+_ejd$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
Type go (Goliath.NET)
--go-name REGEX Valid name regex pattern (!^[A-Za-z]{1,2}(?:`\d+)?$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--go-inline BOOL Inline short methods (True)
--go-remove-inlined BOOL
Remove inlined methods (True)
--go-locals BOOL Restore locals (True)
--go-ints BOOL Decrypt integers (True)
--go-arrays BOOL Decrypt arrays (True)
--go-sn BOOL Remove anti strong name code (True)
Type il (ILProtector)
--il-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
Type mc (MaxtoCode)
--mc-name REGEX Valid name regex pattern (!^[oO01l]+$&!^[A-F0-9]{20,}$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--mc-cp INT String code page (936)
Type mp (MPRESS)
--mp-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
Type rm (Rummage)
--rm-name REGEX Valid name regex pattern (!.)
Type sk (Skater .NET)
--sk-name REGEX Valid name regex pattern (!`[^0-9]+&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
Type sa (SmartAssembly)
--sa-name REGEX Valid name regex pattern (^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--sa-error BOOL Remove automated error reporting code (True)
--sa-tamper BOOL Remove tamper protection code (True)
--sa-memory BOOL Remove memory manager code (True)
Type sn (Spices.Net)
--sn-name REGEX Valid name regex pattern (!^[a-zA-Z0-9]{1,2}$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
--sn-inline BOOL Inline short methods (True)
--sn-remove-inlined BOOL
Remove inlined methods (True)
--sn-ns1 BOOL Clear namespace if there's only one class in it (True)
--sn-rsrc BOOL Restore resource names (True)
Type xc (Xenocode)
--xc-name REGEX Valid name regex pattern (!^[oO01l]{4,}$&!^(get_|set_|add_|remove_|_)?[x_][a-f0-9]{16,}$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$)
String decrypter types
//如何使用字符串解密器
none Don't decrypt strings
//不解密
default Use default string decrypter type (usually static)
//默認(?)
static Use static string decrypter if available
//靜態(?)
delegate Use a delegate to call the real string decrypter
//建立一個委託,傳入相應參數,獲取解密後的字符串
emulate Call real string decrypter and emulate certain instructions
//模擬(?)
Multiple regexes can be used if separated by '&'.
//若是要用多個正則,可使用&鏈接
Use '!' if you want to invert the regex. Example: !^[a-z\d]{1,2}$&!^[A-Z]_\d+$&^[\w.]+$
//要反轉正則表達式可使用"!"
Examples:
de4dot.exe -r c:\my\files -ro c:\my\output
de4dot.exe file1 file2 file3
de4dot.exe file1 -f file2 -o file2.out -f file3 -o file3.out
de4dot.exe file1 --strtyp delegate --strtok 06000123
de4dot的參數格式是:先輸入全局參數,再輸入文件參數/去混淆器參數(這2個不用分順序)
好比:de4dot.exe --dont-rename x.exe --strtype delegate --strtok 0x0600001F
1.Options(全局參數)
--dont-rename
和翻譯同樣,有的時候要用,由於混淆器會對反射代碼特別處理,而de4dot可能沒有處理好,致使反射時出錯
能夠看個人這個帖子 https://www.52pojie.cn/forum.php?mod=viewthread&tid=762380 裏面就是由於de4dot沒正確處理反射代碼,致使須要加上這個參數從新破解一次
--preserve-*
至關於dnSpy中的這些選項,有的時候要加上
<ignore_js_op>
-v和-vv
有時de4dot就拋出個"Hmmmm... something didn't work. Try the latest version.",誰也不知道爲何de4dot會不起做用。因此須要添加-v或-vv使de4dot顯示更詳細的信息。
2.File Options(局部參數)
-p TYPE
若是不指明這個參數,de4dot會自動查明混淆器類型,而且使用對應的去混淆器來去混淆。
若是查明有多個混淆器,則使用查明的的第一個混淆器對應的去混淆器來去混淆。
tuts4you上有一個crackme,加了2層殼 https://forum.tuts4you.com/topic/36942-crackme-unpackme-deepsea-obfuscator-41-and-cryptoobfuscator/
<ignore_js_op> UnpackMe & CrackMe .rar
若是咱們直接把它拖入de4dot
<ignore_js_op>
<ignore_js_op>
打開dnSpy,能夠發現這個和沒脫殼同樣。
因此咱們須要手動指定先去哪一層混淆
這裏咱們用-p ds(ds是DeepSea)
<ignore_js_op>
<ignore_js_op>
能夠發現效果很是好,再把"UnpackMe & CrackMe -cleaned.exe"直接拖入de4dot,讓de4dot處理剩下的那一個混淆器,完成
<ignore_js_op>
--*-name REGEX
沒啥說的,可是挺有用。
如今de4dot這麼有名,不少時候混淆器爲了逃避de4dot重命名使用了合法字符來重命名,好比我寫了一個重命名:正則表達式
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
public
static
class
Renamer
{
private
static
readonly
Regex _validNameRegex =
new
Regex(
"^[a-zA-Z_<{$][a-zA-Z_0-9<>{}$.`-]*$"
);
private
static
void
RenameAll(ModuleDef module)
{
foreach
(TypeDef type
in
module.GetTypes())
if
(!type.IsGlobalModuleType)
{
type.Namespace = GenerateNamespaceName();
type.Name = GenerateName();
foreach
(FieldDef field
in
type.Fields)
field.Name = GenerateName();
foreach
(MethodDef method
in
type.Methods)
{
if
(!(method.IsSpecialName || method.IsAbstract || method.IsVirtual))
method.Name = GenerateName();
foreach
(ParamDef param
in
method.ParamDefs)
param.Name = GenerateName();
}
}
}
private
static
string
GenerateName()
{
StringBuilder stringBuilder;
string
name;
do
{
stringBuilder =
new
StringBuilder(_random.Next(10, 30));
for
(
int
i = 0; i < stringBuilder.Capacity; i++)
stringBuilder.Append(_nameChars[_random.Next(_nameChars.Length)]);
name = stringBuilder.ToString();
}
while
(!_validNameRegex.IsMatch(name));
return
name;
}
private
static
string
GenerateNamespaceName()
{
string
name;
name = GenerateName();
foreach
(
string
part
in
name.Split(
'.'
))
if
(!_validNameRegex.IsMatch(part))
return
GenerateNamespaceName();
return
name;
}
}
|
<ignore_js_op>
de4dot的默認正則表達式對這個重命名徹底無效,因此咱們使用參數--un-name "^[*刪掉留下星號]",表示重命名全部內容
<ignore_js_op>
<ignore_js_op>
--strtyp TYPE和--strtok METHOD
這2個參數通常一塊兒用,不少狀況下還會和"-p un"一塊兒用,--strtyp通常只接delegate,即--strtyp delegate,由於我把剩下的none static emulate default都試了一遍,沒啥用...
--strtok接一個方法token,好比剛纔這個crackme,就能夠直接解密字符串來破解
演示一遍:
用dnSpy打開剛纔的crackme,隨便翻(翻不出能夠同dnspy調試)
<ignore_js_op>
能夠發現我鼠標指着的方法是字符串解密器
<ignore_js_op>
複製出token
我只須要解密字符串,而de4dot會自動使用對應的去混淆器,因此我還要指定-p un
<ignore_js_op>
dnspy打開解密以後的程序集,找到Form1類,看看哪些方法符合這個簽名:void XX(object,EventArgs)
<ignore_js_op>
<ignore_js_op>
是否是很是簡單呢app
https://www.52pojie.cn/forum.php?mod=viewthread&tid=762674dom