0%

概述

有的反调试会检测23946端口是否占用,使用其他端口即可绕过此反调试。
可以使用./android_server -p12345指定端口,也可以使用IDA逆向,修改默认端口。

测试版本

IDA 7.0

patch

使用IDA打开android_server,搜索字符串Listening on,定位到引用位置。
按下F5反编译,重命名端口号变量。按下x,向上搜索找到赋值位置(可能有多处),patch即可。
附上偏移值:

1
2
0xAFE0 LDR     R2, =23946
0xB220 LDR R1, =23946

参考

浅谈android反调试之 转发端口

概述

修改安卓内核源码,绕过对/proc/$pid/stateStateTracerPid字段,以及/proc/$pid/wchan的反调试检测

目标文件

打开内核源码目录,/fs/proc下的base.carray.c

修改点

base.c

proc_pid_wchan函数

最后一个else分支改成

1
2
3
4
5
6
else
{ //修改部分
if(strstr(symname,"trace"))
return sprintf(buffer, "%s", "sys_epoll_wait");
return sprintf(buffer, "%s", symname);
}

因为/proc/pid/wchan 和 /proc/pid/task/pid/wchan在调试状态下,里面内容为ptrace_stop, 非调试的状态下为ep_poll

array.c

1. task_state_array字符数组

将4和8对应的字符("T (stopped)""t (tracing stop)"
都改成"S (sleeping)"

2. task_state函数

与前文(逆向修改安卓内核 x64 过TracerPID反调试)目的一致,置TracerPid为0
将参数tpid改为0即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
seq_printf(m,
"State:\t%s\n"
"Tgid:\t%d\n"
"Pid:\t%d\n"
"PPid:\t%d\n"
"TracerPid:\t%d\n"
"Uid:\t%d\t%d\t%d\t%d\n"
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
task_tgid_nr_ns(p, ns),
pid_nr_ns(pid, ns),
//修改部分
ppid, /*tpid*/0,
from_kuid_munged(user_ns, cred->uid),
from_kuid_munged(user_ns, cred->euid),
from_kuid_munged(user_ns, cred->suid),
from_kuid_munged(user_ns, cred->fsuid),
from_kgid_munged(user_ns, cred->gid),
from_kgid_munged(user_ns, cred->egid),
from_kgid_munged(user_ns, cred->sgid),
from_kgid_munged(user_ns, cred->fsgid));

效果

使用调试器附加后,cd到/proc/$pid/,执行以下命令:
head -8 status
cat wchan

参考

Android反调试——从源码入手

建议在git bash下操作

由于解压kernel.gz时使用的不是命令行,导致没有看到输出信息gzip trailing garbage ignored,进而没有对这些数据进行处理,浪费了很多时间。

概述

直接修改内核,降维打击绕过反调试。
如果有内核源码以及环境,当然可以通过直接修改源码的方式生成boot.img
在无内核源码(或者还没配置安卓源码编译环境)的情况下则只能通过逆向来修改内核。

阅读全文 »

步骤

src/main目录下新建jniLibs文件夹 ,添加cpu架构文件夹,如armeabi-v7a,把so文件复制进去即可。
编译时会自动打包。

配置build.gradleandroid.defaultConfig中的ndk.abiFilters

1
2
3
4
5
6
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a'
}
}

参考

Android studio添加第三方库和so

Reverse

Very easy

得到一个pyc文件,在线反编译得到python源码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 import base64
correct = 'VlxRV2uAiXOPeSWPhiOCaY91JGOJj4Qgj4JVhlVigyNt'
def encode(message):
s = ''
for i in message:
x = ord(i) ^ 32
print ord(i)
x = x + 16
s += chr(x)
return base64.b64encode(s)


flag = ''
decode()
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
print 'correct'
else:
print 'wrong'

逻辑是将输入的字符串逐位与32异或,再加十六,转回ascii码。

阅读全文 »

概述

在模板类中使用输出流重载发现报错,g++提示

warning: friend declaration ‘std::ostream& operator<<(std::ostream&, const A&)’ declares a non-template function
note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
增加<>后依旧报错,遂百度之,解决。

原因

定义的友元函数还是一个模版,要实例化为参数变元后才能使用。也就是说,即使上面的友元看起来像函数定义,但是若没有经过参数化,编译器就不会生成该函数的代码
关于操作符的友元模版函数重载
个人理解是由于友元函数还没有给出声明(或者说是定义),编译器识别不出来。所以可以在类之前预先声明,而又因为该函数使用了类名,所以类名也要预先声明。

解决方法

1.在类内部加上友元函数体(不推荐)

2.在类的定义之前对类和友元函数进行预声明,并在内部加上<>

即在类定义前加上如下代码:

1
2
template <typename T> class A;
template <typename T> ostream &operator<< (ostream &out, const A<T> &a);

在类定义中给输出流重载函数加上<>:

1
2
public:
friend ostream &operator<< <>(ostream &, const A<T> &);

注意:重载函数定义时不需要加上<>

与其他友元函数定义类似:

1
2
3
4
5
6
7
8
9
10
template <typename T>
ostream &operator<< (ostream &out, const A<T> &a)
{
for (int i = 0; i < a.length; i++)
{
out << a[i] << " ";
}
return out;
}

3.在类中再使用一次模板(自用)

参考关于操作符的友元模版函数重载
直接修改类定义中的输出流重载函数为:

1
2
3
public:
template <typename T1>
friend ostream &operator<<(ostream &, const A<T1> &);

重载函数定义不需要修改为T1(当然改也行)

参考

C++ 模板类友元之输出流操作符重载
关于操作符的友元模版函数重载

获取指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A
{
public:
static void staticmember() { cout << "static" << endl; } //static member
void nonstatic() { cout << "nonstatic" << endl; } //nonstatic member
virtual void virtualmember() { cout << "virtual" << endl; }; //virtual member
};
int main()
{
A a;
//static成员函数,取得的是该函数在内存中的实际地址,而且因为static成员是全局的,所以不能用A::限定符
void (*ptrstatic)() = &A::staticmember;
//nonstatic成员函数 取得的是该函数在内存中的实际地址
void (A::*ptrnonstatic)() = &A::nonstatic;
//虚函数取得的是虚函数表中的偏移值,这样可以保证能过指针调用时同样的多态效果
void (A::*ptrvirtual)() = &A::virtualmember;
//函数指针的使用方式
ptrstatic();
(a.*ptrnonstatic)();
(a.*ptrvirtual)();
}

在map中使用指针

直接使用对应类型也是可以的,比如:

1
map<string, void (A::*)()> zeroParmsFuns;

不过为了方便起见,还是自定义类型吧

1
2
typedef void (A::*func)();
map<string, func> zeroParmsFuns;

使用迭代器来遍历map,funcName是函数名,对应map的key

1
2
3
4
5
map<string, func>::iterator iter = zeroParmsFuns.find(funcName);
if (iter != zeroParmsFuns.end())
{
(this->*(iter->second))();
}

参考

C++中怎么获取类的成员函数的函数指针?
C++ 类内函数指针的使用的使用

概述

中文字符串在编辑界面正常显示,编译生成的exe中文乱码。源文件编码为UTF-8,设置输出的可执行文件编码为GB2312后正常显示。
解决方案:添加编译参数-fexec-charset=GB2312

修改方法

1. tasks.json中直接使用g++的情况

具体方法:
在tasks[args]中添加"-fexec-charset=GB2312"

1. tasks.json中使用make的情况

在makefile中添加-fexec-charset=GB2312
比如上一篇博文中的makefile,则在CCOBJFLAG后添加该参数,变为

1
CCOBJFLAG := $(CCFLAG) -c -fexec-charset=GB2312

修正

发现makefile存在问题,仅会编译比main.cpp更新的依赖文件,导致每次都要make两次才能正常调试。已修改$?$^

$@ –代表目标文件(target)
$^ –代表所有的依赖文件(components)
$< –代表第一个依赖文件(components中最左边的那个)
$? –代表比目标还要新的依赖文件列表

概述

之前从知乎抄的配置只能编译单文件源文件,编译多文件的话需要手动修改g++编译参数(不能忍啊→_→),于是搜索之,找到解决方案。
关键词:makefile

环境准备

原本使用VSCode就可以正常进行编译调试等操作。
已安装make工具并添加到环境变量,我自己用的是mingw32-make
(也可使用msys提供的工具包,度盘链接: https://pan.baidu.com/s/1zJBcS6tjfXlwg1kP6VnLSg 提取码: f9ya)

具体方案

构建makefile模板

我基本是直接复制参考博文里的模板(修改标准库为17),内容如下

1
2
3
4
5
6
7
8
9
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# originating https://github.com/TheNetAdmin/Makefile-Templates
# tool marcros
CC := g++
CCFLAG := -std=c++17
DBGFLAG := -g
CCOBJFLAG := $(CCFLAG) -c

# path marcros
BIN_PATH := bin
OBJ_PATH := obj
SRC_PATH := src
DBG_PATH := debug

# compile marcros
TARGET_NAME := main
ifeq ($(OS),Windows_NT)
TARGET_NAME := $(addsuffix .exe,$(TARGET_NAME))
endif
TARGET := $(BIN_PATH)/$(TARGET_NAME)
TARGET_DEBUG := $(DBG_PATH)/$(TARGET_NAME)
MAIN_SRC := src/main.cpp

# src files & obj files
SRC := $(foreach x, $(SRC_PATH), $(wildcard $(addprefix $(x)/*,.c*)))
OBJ := $(addprefix $(OBJ_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC)))))
OBJ_DEBUG := $(addprefix $(DBG_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC)))))

# clean files list
DISTCLEAN_LIST := $(OBJ) \
$(OBJ_DEBUG)
CLEAN_LIST := $(TARGET) \
$(TARGET_DEBUG) \
$(DISTCLEAN_LIST)

# default rule
default: all

# non-phony targets
$(TARGET): $(OBJ)
$(CC) $(CCFLAG) -o $@ $^

$(OBJ_PATH)/%.o: $(SRC_PATH)/%.c*
$(CC) $(CCOBJFLAG) -o $@ $<

$(DBG_PATH)/%.o: $(SRC_PATH)/%.c*
$(CC) $(CCOBJFLAG) $(DBGFLAG) -o $@ $<

$(TARGET_DEBUG): $(OBJ_DEBUG)
$(CC) $(CCFLAG) $(DBGFLAG) $^ -o $@

# phony rules
.PHONY: all
all: $(TARGET)

.PHONY: debug
debug: $(TARGET_DEBUG)

.PHONY: clean
clean:
@echo CLEAN $(CLEAN_LIST)
@rm -f $(CLEAN_LIST)

.PHONY: distclean
distclean:
@echo CLEAN $(CLEAN_LIST)
@rm -f $(DISTCLEAN_LIST)

目录结构

src文件夹下放源文件以及头文件,后面还要需要修改.vscode中的task.jsonlaunch.json
注意:如果使用本文中的makefle,包含主函数的源文件名必须为main.cpp

task.json

如果你使用的是msys的工具包,那command就写make
按快捷键Ctrl+Shift+B可以执行仅生成命令(build)
(在微软输入法中文模式时会出现表情窗口←_←)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "mingw32-make",
"args": [
"default"
],
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
},
{
"label": "build-debug",
"command": "mingw32-make",
"args": [
"debug"
],
"type": "shell"
},
{
"label": "clean",
"command": "mingw32-make",
"args": [
"clean"
],
"type": "shell"
}
]
}

launch.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

// https://github.com/Microsoft/vscode-cpptools/blob/master/launch.md
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/debug/main.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/debug/",
"environment": [],
"externalConsole": true,
"internalConsoleOptions": "neverOpen",
"MIMode": "gdb",
"miDebuggerPath": "gdb.exe", // 调试器路径,Windows下后缀不能省略,Linux下则去掉
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": false,
}
],
"preLaunchTask": "build-debug" // 调试会话开始前执行的任务,一般为编译程序。与tasks.json的label相对应
}
]
}

配置完成

enjoy it!
😉

参考

VS Code 配置 C/C++ 环境