-
-
[转帖]Ghidra 脚本
-
发表于: 2020-9-29 16:20 6351
-
Ghidra是由NSA开发的免费和开源的逆向工程工具,工具的文档和实例比较丰富学习起来阻力小。本着尝鲜的目的来学习工具脚本才有这了这篇记录性的文章,希望对你有所帮助。
转载来自安全客
运行控制台打印出Hello World。
控制台输出如下:
脚本中使用currentProgram来获取符号表,这里currentProgram为抽象类GhidraScript提供的变量。 软件中的参数和信息都是通过这些变量来获取的,常用的变量有如下几个(文档翻译,机器翻译):
Function对象可以操作已经识别的函数,比如引用、函数内逻辑的分析、以及函数内的修改。
控制台输出信息如下:
使用的api说明:
控制台信息如下:
我们拿到Function对象需要借助DecompInterface对象来做更多事情,上面getDecompInterface()可以定式写成这样,因我们只需要拿到DecompInterface对象其他的不用考虑。
decompInterface.decompileFunction(function,0,monitor); 参数解析:反编译function,设置等待时间,monitor为常量。通过这个api可以拿到DecompileResults对象,这个对象中存在HighFunction对象变量,HighFunction对象中getPcodeOps()函数可以返回值pcode迭代器,循环迭代就能获取函数里对应的pcode了。
打印输出了伪C字符
DecompileResults 调用getDecompiledFunction()函数返回DecompiledFunction对象,这个对象中的getC()方法可以返回编译好伪C。当然这里输出伪C并不是唯一方法,另外还有两种方法也可以输出伪C。因为有些需求场景使用伪C字符串并不方便,所以需要另外更适合编程的方法,这个留在下一部分。
------ 分割线 ----------
在有了基础知识后就可以根据需求来编写脚本,比如在挖Iot注入漏洞的时候利用脚本去过滤常量字串不可控字串就会非常节省时间。
选择跟踪 system 函数
找到疑似函数还可以增加调用栈跟踪:
public
class
HelloWorld extends GhidraScript {
public void run() throws Exception {
printf(
"Hello World\n"
);
/
/
格式化输出
println(
"Hello World"
);
/
/
打印字符串并换行
printerr(
"Hello World"
);
/
/
错误消息打印控制台显示红色
}
}
public
class
HelloWorld extends GhidraScript {
public void run() throws Exception {
printf(
"Hello World\n"
);
/
/
格式化输出
println(
"Hello World"
);
/
/
打印字符串并换行
printerr(
"Hello World"
);
/
/
错误消息打印控制台显示红色
}
}
public
class
HelloWorld extends GhidraScript {
@Override
public void run() throws Exception {
/
/
TODO Add User Code Here
SymbolTable st
=
currentProgram.getSymbolTable();
SymbolIterator
iter
=
st.getSymbolIterator(true);
int
count
=
0
;
while
(
iter
.hasNext() && !monitor.isCancelled()) {
Symbol sym
=
iter
.
next
();
if
(sym !
=
null) {
printf(
"\t%s\n"
,sym.getName());
count
+
+
;
}
}
println(count
+
" symbols"
);
}
}
public
class
HelloWorld extends GhidraScript {
@Override
public void run() throws Exception {
/
/
TODO Add User Code Here
SymbolTable st
=
currentProgram.getSymbolTable();
SymbolIterator
iter
=
st.getSymbolIterator(true);
int
count
=
0
;
while
(
iter
.hasNext() && !monitor.isCancelled()) {
Symbol sym
=
iter
.
next
();
if
(sym !
=
null) {
printf(
"\t%s\n"
,sym.getName());
count
+
+
;
}
}
println(count
+
" symbols"
);
}
}
public
class
HelloWorld extends GhidraScript {
@Override
public void run() throws Exception {
FunctionIterator iterator2
=
currentProgram.getListing().getFunctions(true);
for
(Function function : iterator2) {
printf(
"\t%s\n"
,function.getName());
}
}
}
public
class
HelloWorld extends GhidraScript {
@Override
public void run() throws Exception {
FunctionIterator iterator2
=
currentProgram.getListing().getFunctions(true);
for
(Function function : iterator2) {
printf(
"\t%s\n"
,function.getName());
}
}
}
public
class
HelloWorld extends GhidraScript {
@Override
public void run() throws Exception {
FunctionIterator iterator2
=
currentProgram.getListing().getFunctions(true);
for
(Function function : iterator2) {
if
(function.getName().equals(
"write"
)){
printf(
"\t%s @ %s\n"
,function.getName(),function.getEntryPoint());
Reference[] references
=
getReferencesTo(function.getEntryPoint());
for
(Reference reference : references) {
Function referencefunction
=
getFunctionContaining(reference.getFromAddress());
if
(referencefunction!
=
null&& !referencefunction.isThunk())
printf(
"\t\t%s @ %s\n"
,referencefunction.getName(),referencefunction.getEntryPoint().toString());
}
}
}
}
}
public
class
HelloWorld extends GhidraScript {
@Override
public void run() throws Exception {
FunctionIterator iterator2
=
currentProgram.getListing().getFunctions(true);
for
(Function function : iterator2) {
if
(function.getName().equals(
"write"
)){
printf(
"\t%s @ %s\n"
,function.getName(),function.getEntryPoint());
Reference[] references
=
getReferencesTo(function.getEntryPoint());
for
(Reference reference : references) {
Function referencefunction
=
getFunctionContaining(reference.getFromAddress());
if
(referencefunction!
=
null&& !referencefunction.isThunk())
printf(
"\t\t%s @ %s\n"
,referencefunction.getName(),referencefunction.getEntryPoint().toString());
}
}
}
}
}
public
class
HelloWorld extends GhidraScript {
private DecompInterface decompInterface
=
null;
@Override
public void run() throws Exception {
decompInterface
=
getDecompInterface();
FunctionIterator iterator2
=
currentProgram.getListing().getFunctions(true);
for
(Function function : iterator2) {
if
(function.getName().equals(
"FUN_000aeabc"
)){
printf(
"\t%s @ %s\n"
,function.getName(),function.getEntryPoint());
DecompileResults results
=
decompInterface.decompileFunction(function,
0
,monitor);
Iterator<PcodeOpAST> iterator
=
results.getHighFunction().getPcodeOps();
while
(iterator.hasNext()){
PcodeOpAST op
=
iterator.
next
();
printf(
"%s\n"
,op.toString());
}
}
}
}
private DecompInterface getDecompInterface() throws DecompileException {
DecompileOptions options
=
new DecompileOptions();
DecompInterface ifc
=
new DecompInterface();
ifc.setOptions(options);
ifc.setSimplificationStyle(
"decompile"
);
if
(!ifc.openProgram(this.getCurrentProgram())) {
throw new DecompileException(
"Decompiler"
,
"Unable to initialize: "
+
ifc.getLastMessage());
}
return
ifc;
}
}
public
class
HelloWorld extends GhidraScript {
private DecompInterface decompInterface
=
null;
@Override
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)