-
-
[原创]SCTF low_re出题思路
-
发表于: 2022-1-4 19:43 14358
-
这个题其实算是逆向题, 考虑到这个题不是常规逆向思路, 并且有点谜语, 所以我把这个题放misc里面了.
出题人比较菜, 如果给师傅们造成了不好的体验, 轻点骂, orz.
这个题目的预期解是通过pintool之类的插桩工具进行指令计数来进行爆破, 但是我也看到有一些师傅使用钩子来获得信息的一些思路, 甚至于做了一些vmp的逆向, 师傅们tql.
这里是单字节加密(所以可以使用侧信道爆破)
使用python pyminifier的混淆功能去混淆python代码
虽然有一种乱码混淆, 但是可能会导致这样那样的问题, 我就没有使用了
混淆出来之后可能点错误, 手动改改就ok了.
在文件的开头记得加上python3的声明 不然会转化失败
网上python的一个GCC编译exe的脚本
这里的unicode是因为winmain, 如果不用unicode会报错.
这样就生成了exe
网上找一个"学习"版的加壳软件, 关闭内存保护, 这样就可以进行插桩了.
师傅们基本上都是用的官方给的代码来构建, 但是pin官方给的指令计数是算了库的, 这样的话计算出来的指令正常波动就会非常大, 所以我使用了2560次的hash加密, 希望能够使得正确答案的指令大小更为明显, 但是我自己爆破的时候, 如果从头开始爆破, 在得到最后几个字符的时候可能会发生错误. 在和小组另外一个师傅@Cr0ssx2交流之后, 发现如果不计算库的时候指令波动会非常小.
下载地址https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-binary-instrumentation-tool-downloads.html
pin工具可以实现不算库的爆破, 但是官方好像没有给不计算库的指令的代码, 需要自己去写判断, 这里我做的限制条件是 exe的首地址 <= 需要计数指令的地址 <= exe的结束地址.
source/MyPinTool/MyPinTool.cpp: (用VS打开.vcxproj后缀文件就可以进行写代码了)
另外一款插桩工具dynamorio.这款工具的爆破其实比pin工具更快, 但是inscount.cpp的指令输出是消息框, 需要自己做一些改动.
这款工具的官方给的代码是有不计算库的选项的.
build官方文档:https://dynamorio.org/page_building.html
接下来直接打开build/api/samples/DynamoRIO_samples.sln就可以进行写代码编译了
修改后的inscount.cpp:
这里可以用C++ 的windows api来进行爆破, 使用重定向输入和输出创建子进程.
微软的官方文档里面相应的样例代码:
https://docs.microsoft.com/zh-cn/windows/win32/procthread/creating-a-child-process-with-redirected-input-and-output
我使用的是winpwn这个工具来进行爆破, 我稍微看了一下程序创建过程, 本质上还是python去调用windows api, 和C++调用windows API大致一样
爆破脚本:
这里值得注意的是, 最后输出的Count xxx 是输出到错误信息里面的, 并且是以'\n'结尾所以不能直接使用recvline().
winpwn部分源代码:
winpwn调用了win.py
write相关调用:
import
hashlib
import
sys
def
_rc4_crypt(key, data, dataLen):
out
=
[]
s_box
=
list
(
range
(
256
))
j
=
0
for
i
in
range
(
256
):
j
=
(j
+
s_box[i]
+
ord
(key[i
%
len
(key)]))
%
256
s_box[i], s_box[j]
=
s_box[j], s_box[i]
for
x
in
range
(dataLen):
i
=
(i
+
1
)
%
256
j
=
(j
+
s_box[i])
%
256
t
=
s_box[i]
s_box[i]
=
s_box[j]
s_box[j]
=
t
ti
=
(s_box[i]
+
(s_box[j]
%
256
))
%
256
t
=
s_box[ti]
while
(
len
(out) < x
+
1
):
out.append(
0
)
out[x]
=
data[x] ^ t
return
out
def
linux_srand(seed):
if
seed
=
=
0
:
seed
=
1
word
=
seed
seed
=
seed &
0xffffffff
global
linux_status
global
linux_r
linux_status
=
0
linux_r
=
[
0
]
*
(
344
+
linux_status)
linux_r[
0
]
=
seed
for
i
in
range
(
1
,
31
):
if
(word <
0
):
hi
=
(
-
word)
/
/
127773
hi
=
-
hi
lo
=
(
-
word)
%
127773
lo
=
-
lo
else
:
hi
=
word
/
/
127773
lo
=
word
%
127773
word
=
((
16807
*
lo))
-
((
2836
*
hi))
if
word <
0
:
word
=
(
2147483647
+
word) &
0xffffffff
linux_r[i]
=
word
for
i
in
range
(
31
,
34
):
linux_r[i]
=
linux_r[i
-
31
]
for
i
in
range
(
34
,
344
):
linux_r[i]
=
(((linux_r[i
-
31
]
+
linux_r[i
-
3
]) &
0xffffffff
)
%
(
1
<<
32
)) &
0xffffffff
def
linux_rand():
global
linux_status
global
linux_r
linux_r.append(
0
)
linux_r[
344
+
linux_status]
=
(((linux_r[
344
+
linux_status
-
31
]
+
linux_r[
344
+
linux_status
-
3
]) &
0xffffffff
)
%
(
1
<<
32
)) &
0xffffffff
linux_status
+
=
1
return
linux_r[
344
+
linux_status
-
1
] >>
1
print
(
"hello challanger"
)
flag
=
input
(
"please input your flag:\n"
)
if
(
type
(flag) !
=
str
):
print
(
"error"
)
sys.exit()
if
(
len
(flag) !
=
17
):
sys.exit()
flag
=
list
(bytes(flag, encoding
=
'utf-8'
))
flag
=
_rc4_crypt(
'Sycl0ver'
, flag,
len
(flag))
for
i
in
range
(
len
(flag)):
linux_srand(flag[i])
flag[i]
=
str
(linux_rand())
ciphertext
=
[
'ee197bbac1b0e09c425e1dfd30cea2506bd493a674c4de90d9afbe5abc700b06'
,
'1a6aafb16a23ffde40c426d5c87f5afcc77fffc96cf041dc8dd2c47e706a7ecb'
,
'62c62ce7768a4836b10495317a32da6e3943d522bc3b9797ff0a44931e966a31'
,
'e6222354b50e4d33d73314b515b325633e57a105758e20aca23eb2dadd625f3f'
,
'78f92a6ad9ffcec47f30e3ca3d18065bdba9c020ff5f477b801d11efdfaa9cd0'
,
'127291de1f4cbbb35c41556a3c6d5a64f08661bc7ed394ea6210354e6218ad93'
,
'62c62ce7768a4836b10495317a32da6e3943d522bc3b9797ff0a44931e966a31'
,
'52080868c07a9ef5646b5f0b198f04f013cf23cfbfb06123d8f2fdd63d359123'
,
'f69b52599973fc5915ad1d435236863252dc3fd460989bd9f56ffc199ef8ff36'
,
'e9552f8c3e518306524fa9c9728ad6dee88fa611aa3068c169217f173964f9b4'
,
'54cb43f463ea082699131b71d45fb0384f8c2f598e8f0072b960b4add731e048'
,
'97e45e15c74f71ea59ffffb40298f2e5dec119c2205e434e3a0d2510c331037f'
,
'51b7d78cfe25ede262fd85a65b24721f076ab9dd6562403878ca5cde1ebf3219'
,
'a1cd6c7990abb6b271695381d78898ec5c4880fbc0f6a0c9fda064422f21361e'
,
'85ddd3721d173367465373f75e190bd937a8dc3588d5d82ebff8104dec88ac3e'
,
'd6eeac4ea40f9513391ef0bf72aa2fd2588889cb9d5f4cc638ce4d2c5509527b'
,
'5023939dca9273fd767d5e4ea329846f9816af461e170b6db8d20b6e5ff3de8c'
]
for
i
in
range
(
len
(flag)):
for
j
in
range
(
2560
):
s
=
hashlib.sha256()
s.update(bytes(flag[i], encoding
=
'utf-8'
))
flag[i]
=
s.hexdigest()
#print("'" + flag[i]+ "',")
if
(flag[i] !
=
ciphertext[i]):
sys.exit()
print
(
"you are right"
)
sys.exit()
import
hashlib
import
sys
def
_rc4_crypt(key, data, dataLen):
out
=
[]
s_box
=
list
(
range
(
256
))
j
=
0
for
i
in
range
(
256
):
j
=
(j
+
s_box[i]
+
ord
(key[i
%
len
(key)]))
%
256
s_box[i], s_box[j]
=
s_box[j], s_box[i]
for
x
in
range
(dataLen):
i
=
(i
+
1
)
%
256
j
=
(j
+
s_box[i])
%
256
t
=
s_box[i]
s_box[i]
=
s_box[j]
s_box[j]
=
t
ti
=
(s_box[i]
+
(s_box[j]
%
256
))
%
256
t
=
s_box[ti]
while
(
len
(out) < x
+
1
):
out.append(
0
)
out[x]
=
data[x] ^ t
return
out
def
linux_srand(seed):
if
seed
=
=
0
:
seed
=
1
word
=
seed
seed
=
seed &
0xffffffff
global
linux_status
global
linux_r
linux_status
=
0
linux_r
=
[
0
]
*
(
344
+
linux_status)
linux_r[
0
]
=
seed
for
i
in
range
(
1
,
31
):
if
(word <
0
):
hi
=
(
-
word)
/
/
127773
hi
=
-
hi
lo
=
(
-
word)
%
127773
lo
=
-
lo
else
:
hi
=
word
/
/
127773
lo
=
word
%
127773
word
=
((
16807
*
lo))
-
((
2836
*
hi))
if
word <
0
:
word
=
(
2147483647
+
word) &
0xffffffff
linux_r[i]
=
word
for
i
in
range
(
31
,
34
):
linux_r[i]
=
linux_r[i
-
31
]
for
i
in
range
(
34
,
344
):
linux_r[i]
=
(((linux_r[i
-
31
]
+
linux_r[i
-
3
]) &
0xffffffff
)
%
(
1
<<
32
)) &
0xffffffff
def
linux_rand():
global
linux_status
global
linux_r
linux_r.append(
0
)
linux_r[
344
+
linux_status]
=
(((linux_r[
344
+
linux_status
-
31
]
+
linux_r[
344
+
linux_status
-
3
]) &
0xffffffff
)
%
(
1
<<
32
)) &
0xffffffff
linux_status
+
=
1
return
linux_r[
344
+
linux_status
-
1
] >>
1
print
(
"hello challanger"
)
flag
=
input
(
"please input your flag:\n"
)
if
(
type
(flag) !
=
str
):
print
(
"error"
)
sys.exit()
if
(
len
(flag) !
=
17
):
sys.exit()
flag
=
list
(bytes(flag, encoding
=
'utf-8'
))
flag
=
_rc4_crypt(
'Sycl0ver'
, flag,
len
(flag))
for
i
in
range
(
len
(flag)):
linux_srand(flag[i])
flag[i]
=
str
(linux_rand())
ciphertext
=
[
'ee197bbac1b0e09c425e1dfd30cea2506bd493a674c4de90d9afbe5abc700b06'
,
'1a6aafb16a23ffde40c426d5c87f5afcc77fffc96cf041dc8dd2c47e706a7ecb'
,
'62c62ce7768a4836b10495317a32da6e3943d522bc3b9797ff0a44931e966a31'
,
'e6222354b50e4d33d73314b515b325633e57a105758e20aca23eb2dadd625f3f'
,
'78f92a6ad9ffcec47f30e3ca3d18065bdba9c020ff5f477b801d11efdfaa9cd0'
,
'127291de1f4cbbb35c41556a3c6d5a64f08661bc7ed394ea6210354e6218ad93'
,
'62c62ce7768a4836b10495317a32da6e3943d522bc3b9797ff0a44931e966a31'
,
'52080868c07a9ef5646b5f0b198f04f013cf23cfbfb06123d8f2fdd63d359123'
,
'f69b52599973fc5915ad1d435236863252dc3fd460989bd9f56ffc199ef8ff36'
,
'e9552f8c3e518306524fa9c9728ad6dee88fa611aa3068c169217f173964f9b4'
,
'54cb43f463ea082699131b71d45fb0384f8c2f598e8f0072b960b4add731e048'
,
'97e45e15c74f71ea59ffffb40298f2e5dec119c2205e434e3a0d2510c331037f'
,
'51b7d78cfe25ede262fd85a65b24721f076ab9dd6562403878ca5cde1ebf3219'
,
'a1cd6c7990abb6b271695381d78898ec5c4880fbc0f6a0c9fda064422f21361e'
,
'85ddd3721d173367465373f75e190bd937a8dc3588d5d82ebff8104dec88ac3e'
,
'd6eeac4ea40f9513391ef0bf72aa2fd2588889cb9d5f4cc638ce4d2c5509527b'
,
'5023939dca9273fd767d5e4ea329846f9816af461e170b6db8d20b6e5ff3de8c'
]
for
i
in
range
(
len
(flag)):
for
j
in
range
(
2560
):
s
=
hashlib.sha256()
s.update(bytes(flag[i], encoding
=
'utf-8'
))
flag[i]
=
s.hexdigest()
#print("'" + flag[i]+ "',")
if
(flag[i] !
=
ciphertext[i]):
sys.exit()
print
(
"you are right"
)
sys.exit()
pyminifier
-
-
obfuscate
pyminifier
-
-
obfuscate
# cython: language_level=3
# cython: language_level=3
import
subprocess
import
sys
import
tempfile
from
Cython.Compiler
import
Main, CmdLine, Options
in_file_name
=
sys.argv[
1
]
source
=
open
(in_file_name).read()
out_file_name
=
in_file_name.replace(
'.py'
,
'.exe'
)
temp_py_file
=
tempfile.NamedTemporaryFile(suffix
=
'.py'
, delete
=
False
)
temp_py_file.write(source.encode())
temp_py_file.flush()
Main.Options.embed
=
'main'
res
=
Main.compile_single(temp_py_file.name, Main.CompilationOptions(), '')
gcc_cmd
=
'gcc -static -municode -DMS_WIN64 -fPIC -O2 %s -Id:\\Python\\Python38\\include -Ld:\\Python\\Python38\\libs -lpython38 -o %s'
%
(res.c_file, out_file_name)
print
(gcc_cmd)
assert
0
=
=
subprocess.check_call(gcc_cmd.split(
' '
))
import
subprocess
import
sys
import
tempfile
from
Cython.Compiler
import
Main, CmdLine, Options
in_file_name
=
sys.argv[
1
]
source
=
open
(in_file_name).read()
out_file_name
=
in_file_name.replace(
'.py'
,
'.exe'
)
temp_py_file
=
tempfile.NamedTemporaryFile(suffix
=
'.py'
, delete
=
False
)
temp_py_file.write(source.encode())
temp_py_file.flush()
Main.Options.embed
=
'main'
res
=
Main.compile_single(temp_py_file.name, Main.CompilationOptions(), '')
gcc_cmd
=
'gcc -static -municode -DMS_WIN64 -fPIC -O2 %s -Id:\\Python\\Python38\\include -Ld:\\Python\\Python38\\libs -lpython38 -o %s'
%
(res.c_file, out_file_name)
print
(gcc_cmd)
assert
0
=
=
subprocess.check_call(gcc_cmd.split(
' '
))
/
*
*
Copyright
2002
-
2020
Intel Corporation.
*
*
This software
is
provided to you as Sample Source Code as defined
in
the accompanying
*
End User License Agreement
for
the Intel(R) Software Development Products (
"Agreement"
)
*
section
1.L
.
*
*
This software
and
the related documents are provided as
is
, with no express
or
implied
*
warranties, other than those that are expressly stated
in
the License.
*
/
/
*
! @
file
*
This
file
contains an ISA
-
portable PIN tool
for
counting dynamic instructions
*
/
#include "pin.H"
#include <iostream>
using std::cerr;
using std::endl;
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Global Variables
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
UINT64 ins_count
=
0
;
bool
runing
=
false;
UINT64 exe_start;
UINT64 exe_size;
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Commandline Switches
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Print
Help
Message
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
INT32 Usage()
{
cerr <<
"This tool prints out the number of dynamic instructions executed to stderr.\n"
"\n"
;
cerr << KNOB_BASE::StringKnobSummary();
cerr << endl;
return
-
1
;
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
VOID docount() { ins_count
+
+
; }
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
VOID Instruction(INS ins, VOID
*
v)
{
ADDRINT addr
=
INS_Address(ins);
if
(exe_start <
=
addr && addr <
=
exe_start
+
exe_size)
/
/
判断指令是否在库中, 若不在, 则进行插桩
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
VOID Image(IMG img, VOID
*
v)
{
if
(IMG_IsMainExecutable(img))
{
exe_start
=
IMG_StartAddress(img);
exe_size
=
IMG_SizeMapped(img);
}
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
VOID Fini(INT32 code, VOID
*
v) {
cerr <<
"Count "
<< ins_count <<
" "
<< exe_start <<
" "
<< exe_size
+
exe_start << endl;
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Main
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
int
main(
int
argc, char
*
argv[])
{
if
(PIN_Init(argc, argv))
{
return
Usage();
}
IMG_AddInstrumentFunction(Image,
0
);
INS_AddInstrumentFunction(Instruction,
0
);
PIN_AddFiniFunction(Fini,
0
);
/
/
Never returns
PIN_StartProgram();
return
0
;
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
eof
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
*
Copyright
2002
-
2020
Intel Corporation.
*
*
This software
is
provided to you as Sample Source Code as defined
in
the accompanying
*
End User License Agreement
for
the Intel(R) Software Development Products (
"Agreement"
)
*
section
1.L
.
*
*
This software
and
the related documents are provided as
is
, with no express
or
implied
*
warranties, other than those that are expressly stated
in
the License.
*
/
/
*
! @
file
*
This
file
contains an ISA
-
portable PIN tool
for
counting dynamic instructions
*
/
#include "pin.H"
#include <iostream>
using std::cerr;
using std::endl;
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Global Variables
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
UINT64 ins_count
=
0
;
bool
runing
=
false;
UINT64 exe_start;
UINT64 exe_size;
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Commandline Switches
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Print
Help
Message
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
INT32 Usage()
{
cerr <<
"This tool prints out the number of dynamic instructions executed to stderr.\n"
"\n"
;
cerr << KNOB_BASE::StringKnobSummary();
cerr << endl;
return
-
1
;
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
VOID docount() { ins_count
+
+
; }
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
VOID Instruction(INS ins, VOID
*
v)
{
ADDRINT addr
=
INS_Address(ins);
if
(exe_start <
=
addr && addr <
=
exe_start
+
exe_size)
/
/
判断指令是否在库中, 若不在, 则进行插桩
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
VOID Image(IMG img, VOID
*
v)
{
if
(IMG_IsMainExecutable(img))
{
exe_start
=
IMG_StartAddress(img);
exe_size
=
IMG_SizeMapped(img);
}
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
VOID Fini(INT32 code, VOID
*
v) {
cerr <<
"Count "
<< ins_count <<
" "
<< exe_start <<
" "
<< exe_size
+
exe_start << endl;
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
Main
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
int
main(
int
argc, char
*
argv[])
{
if
(PIN_Init(argc, argv))
{
return
Usage();
}
IMG_AddInstrumentFunction(Image,
0
);
INS_AddInstrumentFunction(Instruction,
0
);
PIN_AddFiniFunction(Fini,
0
);
/
/
Never returns
PIN_StartProgram();
return
0
;
}
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
/
*
eof
*
/
/
*
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
*
/
git clone https:
/
/
github.com
/
DynamoRIO
/
dynamorio.git
cd dynamorio && mkdir build && cd build
cmake
-
G
"Visual Studio 15"
..
#从这里指定你的VS版本, 2019为16, 2022为17 后面跟上dynamorio的源路径
cmake
-
-
build .
-
-
config RelWithDebInfo
git clone https:
/
/
github.com
/
DynamoRIO
/
dynamorio.git
cd dynamorio && mkdir build && cd build
cmake
-
G
"Visual Studio 15"
..
#从这里指定你的VS版本, 2019为16, 2022为17 后面跟上dynamorio的源路径
cmake
-
-
build .
-
-
config RelWithDebInfo
/
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Copyright (c)
2014
-
2018
Google, Inc.
All
rights reserved.
*
Copyright (c)
2011
Massachusetts Institute of Technology
All
rights reserved.
*
Copyright (c)
2008
VMware, Inc.
All
rights reserved.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
/
/
*
*
Redistribution
and
use
in
source
and
binary forms, with
or
without
*
modification, are permitted provided that the following conditions are met:
*
*
*
Redistributions of source code must retain the above copyright notice,
*
this
list
of conditions
and
the following disclaimer.
*
*
*
Redistributions
in
binary form must reproduce the above copyright notice,
*
this
list
of conditions
and
the following disclaimer
in
the documentation
*
and
/
or
other materials provided with the distribution.
*
*
*
Neither the name of VMware, Inc. nor the names of its contributors may be
*
used to endorse
or
promote products derived
from
this software without
*
specific prior written permission.
*
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
*
AND
ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
*
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
*
ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
*
FOR
ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
*
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
*
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*
CAUSED AND ON
ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY
WAY
*
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
*
DAMAGE.
*
/
/
*
Code Manipulation API Sample:
*
inscount.cpp
*
*
Reports the dynamic count of the total number of instructions executed.
*
Illustrates how to perform performant clean calls.
*
Demonstrates effect of clean call optimization
and
auto
-
inlining with
*
different
-
opt_cleancall values.
*
*
The runtime options
for
this client include:
*
-
only_from_app Do
not
count instructions
in
shared libraries.
*
The options are handled using the droption extension.
*
/
#include "dr_api.h"
#include "drmgr.h"
#include "droption.h"
#include <string.h>
#include<iostream>
#ifdef WINDOWS
# define DISPLAY_STRING(msg) dr_messagebox(msg)
#else
# define DISPLAY_STRING(msg) dr_printf("%s\n", msg);
#endif
#define NULL_TERMINATE(buf) (buf)[(sizeof((buf)) / sizeof((buf)[0])) - 1] = '\0'
static droption_t<
bool
> only_from_app(
DROPTION_SCOPE_CLIENT,
"only_from_app"
, false,
"Only count app, not lib, instructions"
,
"Count only instructions in the application itself, ignoring instructions in "
"shared libraries."
);
/
/
把选项加上only_from_app就可以不进行库的计数
/
*
Application module
*
/
static app_pc exe_start;
/
*
we only have a
global
count
*
/
static uint64 global_count;
/
*
A simple clean call that will be automatically inlined because it has only
*
one argument
and
contains no calls to other functions.
*
/
static void
inscount(uint num_instrs)
{
global_count
+
=
num_instrs;
}
static void
event_exit(void);
static dr_emit_flags_t
event_bb_analysis(void
*
drcontext, void
*
tag, instrlist_t
*
bb,
bool
for_trace,
bool
translating, void
*
*
user_data);
static dr_emit_flags_t
event_app_instruction(void
*
drcontext, void
*
tag, instrlist_t
*
bb, instr_t
*
inst,
bool
for_trace,
bool
translating, void
*
user_data);
DR_EXPORT void
dr_client_main(client_id_t
id
,
int
argc, const char
*
argv[])
{
dr_set_client_name(
"DynamoRIO Sample Client 'inscount'"
,
"http://dynamorio.org/issues"
);
/
*
Options
*
/
if
(!droption_parser_t::parse_argv(DROPTION_SCOPE_CLIENT, argc, argv, NULL, NULL))
DR_ASSERT(false);
drmgr_init();
/
*
Get main module address
*
/
if
(only_from_app.get_value()) {
module_data_t
*
exe
=
dr_get_main_module();
if
(exe !
=
NULL)
exe_start
=
exe
-
>start;
dr_free_module_data(exe);
}
/
*
register events
*
/
dr_register_exit_event(event_exit);
drmgr_register_bb_instrumentation_event(event_bb_analysis, event_app_instruction,
NULL);
/
*
make it easy to tell, by looking at log
file
, which client executed
*
/
dr_log(NULL, DR_LOG_ALL,
1
,
"Client 'inscount' initializing\n"
);
#ifdef SHOW_RESULTS
/
*
also give notification to stderr
*
/
if
(dr_is_notify_on()) {
# ifdef WINDOWS
/
*
ask
for
best
-
effort printing to cmd window. must be called at init.
*
/
dr_enable_console_printing();
# endif
dr_fprintf(STDERR,
"Client inscount is running\n"
);
}
#endif
}
static void
event_exit(void)
{
#ifdef SHOW_RESULTS
char msg[
512
];
int
len
;
len
=
dr_snprintf(msg, sizeof(msg)
/
sizeof(msg[
0
]),
"Instrumentation results: %llu instructions executed\n"
,
global_count);
DR_ASSERT(
len
>
0
);
NULL_TERMINATE(msg);
/
/
DISPLAY_STRING(msg);
/
/
这里是messagebox 把这个数据时间控制台输出就行了
std::cout << msg << std::endl;
#endif /* SHOW_RESULTS */
drmgr_exit();
}
static dr_emit_flags_t
event_bb_analysis(void
*
drcontext, void
*
tag, instrlist_t
*
bb,
bool
for_trace,
bool
translating, void
*
*
user_data)
{
instr_t
*
instr;
uint num_instrs;
#ifdef VERBOSE
dr_printf(
"in dynamorio_basic_block(tag="
PFX
")\n"
, tag);
# ifdef VERBOSE_VERBOSE
instrlist_disassemble(drcontext, tag, bb, STDOUT);
# endif
#endif
/
*
Only count
in
app BBs
*
/
if
(only_from_app.get_value()) {
module_data_t
*
mod
=
dr_lookup_module(dr_fragment_app_pc(tag));
if
(mod !
=
NULL) {
bool
from_exe
=
(mod
-
>start
=
=
exe_start);
dr_free_module_data(mod);
if
(!from_exe) {
*
user_data
=
NULL;
return
DR_EMIT_DEFAULT;
}
}
}
/
*
Count instructions. If an emulation client
is
running with this client,
*
we want to count
all
the original native instructions
and
the emulated
*
instruction but NOT the introduced native instructions used
for
emulation.
*
/
bool
is_emulation
=
false;
for
(instr
=
instrlist_first(bb), num_instrs
=
0
; instr !
=
NULL;
instr
=
instr_get_next(instr)) {
if
(drmgr_is_emulation_start(instr)) {
/
*
Each emulated instruction
is
replaced by a series of native
*
instructions delimited by labels indicating when the emulation
*
sequence begins
and
ends. It
is
the responsibility of the
*
emulation client to place the start
/
stop labels correctly.
*
/
num_instrs
+
+
;
is_emulation
=
true;
/
*
Data about the emulated instruction can be extracted
from
the
*
start label using the accessor function:
*
drmgr_get_emulated_instr_data()
*
/
continue
;
}
if
(drmgr_is_emulation_end(instr)) {
is_emulation
=
false;
continue
;
}
if
(is_emulation)
continue
;
if
(!instr_is_app(instr))
continue
;
num_instrs
+
+
;
}
*
user_data
=
(void
*
)(ptr_uint_t)num_instrs;
#if defined(VERBOSE) && defined(VERBOSE_VERBOSE)
dr_printf(
"Finished counting for dynamorio_basic_block(tag="
PFX
")\n"
, tag);
instrlist_disassemble(drcontext, tag, bb, STDOUT);
#endif
return
DR_EMIT_DEFAULT;
}
static dr_emit_flags_t
event_app_instruction(void
*
drcontext, void
*
tag, instrlist_t
*
bb, instr_t
*
instr,
bool
for_trace,
bool
translating, void
*
user_data)
{
uint num_instrs;
/
*
By default drmgr enables auto
-
predication, which predicates
all
instructions with
*
the predicate of the current instruction on ARM.
*
We disable it here because we want to unconditionally execute the following
*
instrumentation.
*
/
drmgr_disable_auto_predication(drcontext, bb);
if
(!drmgr_is_first_instr(drcontext, instr))
return
DR_EMIT_DEFAULT;
/
*
Only insert calls
for
in
-
app BBs
*
/
if
(user_data
=
=
NULL)
return
DR_EMIT_DEFAULT;
/
*
Insert clean call
*
/
num_instrs
=
(uint)(ptr_uint_t)user_data;
dr_insert_clean_call(drcontext, bb, instrlist_first_app(bb), (void
*
)inscount,
false
/
*
save fpstate
*
/
,
1
, OPND_CREATE_INT32(num_instrs));
return
DR_EMIT_DEFAULT;
}
/
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Copyright (c)
2014
-
2018
Google, Inc.
All
rights reserved.
*
Copyright (c)
2011
Massachusetts Institute of Technology
All
rights reserved.
*
Copyright (c)
2008
VMware, Inc.
All
rights reserved.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
/
/
*
*
Redistribution
and
use
in
source
and
binary forms, with
or
without
*
modification, are permitted provided that the following conditions are met:
*
*
*
Redistributions of source code must retain the above copyright notice,
*
this
list
of conditions
and
the following disclaimer.
*
*
*
Redistributions
in
binary form must reproduce the above copyright notice,
*
this
list
of conditions
and
the following disclaimer
in
the documentation
*
and
/
or
other materials provided with the distribution.
*
*
*
Neither the name of VMware, Inc. nor the names of its contributors may be
*
used to endorse
or
promote products derived
from
this software without
*
specific prior written permission.
*
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
赞赏
- [原创]SCTF low_re出题思路 14359
- [原创]l3hctf两道re的wp 8995
- [原创]强网拟态线上mobile的两道wp 22251
- [原创]android JNI静态注册和动态注册 9489
- [原创]inctf-noodes 9785