Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
bmax121 committed Dec 26, 2020
1 parent 20cc5ca commit e4acd75
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 48 deletions.
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@

# sktrace
# sktrace

## 问题
1. Frida Stalker arm32 测试一直崩溃
2. bl 导致的寄存器改变在下一条指令体现

## 功能
1. 类似 ida 指令 trace 功能
2. 统计寄存器变化,辅助分析,并且可能会有字符串产生,

## todo
1. 改为 C 实现。脱离 python
2. arm32
3.


37 changes: 19 additions & 18 deletions sktrace/sktrace.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const arm64CM = new CModule(`
extern void on_message(const gchar *message);
static void log(const gchar *format, ...);
static void on_exec(GumCpuContext *cpu_context, gpointer user_data);
static void on_arm64_before(GumCpuContext *cpu_context, gpointer user_data);
static void on_arm64_after(GumCpuContext *cpu_context, gpointer user_data);
void hello() {
on_message("Hello form CModule");
Expand Down Expand Up @@ -52,13 +53,13 @@ void transform(GumStalkerIterator *iterator,
gboolean in_target = (gpointer)insn->address >= base && (gpointer)insn->address < end;
if(in_target)
{
// addr,mnem,op_str
log("%p\t%s\t%s", (gpointer)insn->address, insn->mnemonic, insn->op_str);
gum_stalker_iterator_put_callout(iterator, on_arm64_before, (gpointer) insn->address, NULL);
}
gum_stalker_iterator_keep(iterator);
if(in_target)
{
gum_stalker_iterator_put_callout(iterator, on_exec, (gpointer) insn->address, NULL);
gum_stalker_iterator_put_callout(iterator, on_arm64_after, (gpointer) insn->address, NULL);
}
}
}
Expand All @@ -75,25 +76,24 @@ const gchar * cpu_format = "
";
static void
on_exec(GumCpuContext *cpu_context,
on_arm64_before(GumCpuContext *cpu_context,
gpointer user_data)
{
log(cpu_format,
cpu_context->pc, cpu_context->sp,
cpu_context->x[0], cpu_context->x[1], cpu_context->x[2], cpu_context->x[3], cpu_context->x[4],
cpu_context->x[5], cpu_context->x[6], cpu_context->x[7], cpu_context->x[8], cpu_context->x[9],
cpu_context->x[10], cpu_context->x[11], cpu_context->x[12], cpu_context->x[13], cpu_context->x[14],
cpu_context->x[15], cpu_context->x[16], cpu_context->x[17], cpu_context->x[18], cpu_context->x[19],
cpu_context->x[20], cpu_context->x[21], cpu_context->x[22], cpu_context->x[23], cpu_context->x[24],
cpu_context->x[25], cpu_context->x[26], cpu_context->x[27], cpu_context->x[28],
cpu_context->fp, cpu_context->lr
);
}
static void
on_arm64_after(GumCpuContext *cpu_context,
gpointer user_data)
{
}
`, {
on_message: new NativeCallback(messagePtr => {
const message = messagePtr.readUtf8String();
send(message)
console.log(message)
// send(message)
}, 'void', ['pointer']),
});

Expand Down Expand Up @@ -214,17 +214,18 @@ function watcherLib(libname, callback) {


(() => {
console.log('==== sktrace ====');

console.log(`----- start trace -----`);

recv("config", (msg) => {
const payload = msg.payload;
console.log(JSON.stringify(payload))
const libname = payload.libname;
console.log(`libname:${libname}`)
if(payload.spawn) {
//
console.error(`todo: spawn inject not implemented`)
} else {
const modules = Process.enumerateModules();
// const modules = Process.enumerateModules();
const targetModule = Process.getModuleByName(libname);
let targetAddress = null;
if("symbol" in payload) {
Expand Down
5 changes: 3 additions & 2 deletions sktrace/sktrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import os
import frida

from trace import TraceMgr
from sktracemgr import TraceMgr

__version__ = "1.0.0"

Expand Down Expand Up @@ -74,7 +74,7 @@ def main():
"type": "config",
"payload": {}
}
print(args.libname)

config["payload"]["libname"] = args.libname

if args.interceptor.startswith("0x") or args.interceptor.startswith("0X"):
Expand All @@ -84,6 +84,7 @@ def main():

device = frida.get_usb_device(1)
if args.inject_method == "spawn":
raise Exception("working for this ...")
pid = device.spawn([args.target])
config["payload"]["spawn"] = True
else:
Expand Down
61 changes: 34 additions & 27 deletions sktrace/sktracemgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ def add_changed_regs(self, changed_regs_arr):
self.changed_regs_dict[reg_val.keys[0]] = (reg_val.values[0])

def cal_regs_change(self, pre_ctx, ctx):
print_every_inst = True
print_every_change = True
eveny_change_str = None
# ignore pc
if not pre_ctx:
for i in range(31):
Expand All @@ -53,15 +54,21 @@ def cal_regs_change(self, pre_ctx, ctx):
if "sp" not in self.changed_regs_dict:
self.changed_regs_dict["sp"] = []
self.changed_regs_dict["sp"].append(ctx.sp)
if print_every_inst:
print("{}\t;sp={}".format(str(self), ctx.sp))
if print_every_change:
eveny_change_str = ("{}\t; sp={}->{}".format(self.simple_str(), pre_ctx.sp, ctx.sp))
for i in range(31):
if pre_ctx.general_regs[i] != ctx.general_regs[i]:
if "x"+str(i) not in self.changed_regs_dict:
self.changed_regs_dict["x"+str(i)] = []
self.changed_regs_dict["x"+str(i)].append(ctx.general_regs[i])
if print_every_inst:
print("{}\t;x{}={}".format(str(self), str(i), ctx.general_regs[i]))
if print_every_change:
if eveny_change_str:
eveny_change_str += (", x{}={}->{}".format(str(i), pre_ctx.general_regs[i], ctx.general_regs[i]))
else:
eveny_change_str = ("{}\t; x{}={}->{}".format(self.simple_str(), str(i), pre_ctx.general_regs[i], ctx.general_regs[i]))

if print_every_change and eveny_change_str:
print(eveny_change_str)
pass

def try_strings(self):
Expand All @@ -85,18 +92,22 @@ def try_strings(self):

if self.try_strings_set:
# print("strs\t" + str(self.try_strings_set))
print("strs\t" + ",".join(self.try_strings_set))
print("strings\t" + ",".join(self.try_strings_set))

def print_changed_regs(self):
def statistics_changed_regs(self):
if self.changed_regs_dict:
change_line = "chng"
change_line = "statistics"
for reg in self.changed_regs_dict:
change_reg = "\t{}:{}".format(reg, ",".join(self.changed_regs_dict[reg]))
change_line += change_reg
print(change_line)

def simple_str(self):
inst_line = "{}\t{}\t{}".format(self.addr, self.mnem, self.op)
return inst_line

def __str__(self):
inst_line = "{}\t{}\t{}\t{}\t{}\t{}".format("inst", self.addr, self.block, self.size, self.mnem, self.op)
inst_line = "{}\t{}\t{}\t{}\t{}\t{}".format("instruction", self.addr, self.block, self.size, self.mnem, self.op)
return inst_line

class Arm64Ctx:
Expand Down Expand Up @@ -137,19 +148,6 @@ def __str__(self):
return ctx_line


# detail format
'''
tid block addr size [transform times]
tid inst addr mnemonic op
tid ctx addr mnemonic op changed_reg=val
'''
# summary format
'''
tid block addr size inst_addrs
tid inst block size mnemonic op
tid chng {reg:val_list}
tid strs (guess_strs_set)
'''


class TraceMgr:
Expand Down Expand Up @@ -195,6 +193,7 @@ def on_message(self, payload):
self.block_dict[inst.block] = Block(inst.block)
self.block_dict[inst.block].append_inst(inst)
self.inst_dict[inst.addr] = inst
# print(inst)
pass
elif type == 'ctx':
# print(payload)
Expand All @@ -205,23 +204,31 @@ def on_message(self, payload):
val["x20"], val["x21"], val["x22"], val["x23"], val["x24"], val["x25"], val["x26"], val["x27"], val["x28"],
val["fp"], val["lr"])
if ctx.pc not in self.inst_dict:
raise Exception('No inst addr:{},Maybe caused by Interceptor.payload:{}'.format(ctx.pc, payload))
raise Exception("No inst addr:{} maybe caused by Interceptor.payload:{}".format(ctx.pc, payload))
self.inst_dict[ctx.pc].add_execed_ctx(ctx)
self.inst_dict[ctx.pc].cal_regs_change(self.pre_ctx, ctx)
self.pre_ctx = ctx
pass
elif type == "fin":
self.summary()
self.statistics()
pass

def summary(self):
print('''=========================================''')
# statistics
# '''
# tid block addr size inst_addrs
# tid inst block size mnemonic op
# tid chng {reg:val_list}
# tid strs (guess_strs_set)
# '''
def statistics(self):
print('''==================== Statistic Start =====================''')
for block_addr in self.block_dict:
block = self.block_dict[block_addr]
print(block)
for inst in block.insts:
print(inst)
inst.print_changed_regs()
inst.statistics_changed_regs()
inst.try_strings()
print('''==================== Statistic End =====================''')


0 comments on commit e4acd75

Please sign in to comment.