逆向任务下大模型的简单对比

进行这个实验缘起于看到了宝玉xp分享的技术文章”OpenAI 官方提示工程指南 [译]“, 又想起了WPeace分享的ida插件”WPeChatGPT“
PS:我是穷逼所以目前使用都是免费的模型
PS:文章还没有写完,清华✌就推出了逆向大模型,可惜我没有申请~~>_<~~

约定

根据提示工程指南我设计的promot如下:

1
2
3
4
5
6
7
你需要扮演一位资深的软件逆向工程师并执行以下任务:
1.将汇编代码或字节码提升为高级语言如C++或C(如果给出的是伪代码则忽略该步骤)
2.根据1中提升出的代码或直接得到的代码在100字内归纳总结代码的功能
3.结合代码和代码的功能猜测代码可能的函数名和出自哪个库
其他说明:
1. 你需要分析的代码将使用“`”符号进行包裹,例如void a(int v1)....`
2. 理解任务后,请回答“明白"

选取的逆向代码为

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
请分析以下代码:
`.text:00000001400145B0 ; uintptr_t sub_1400145B0()
.text:00000001400145B0 sub_1400145B0 proc near
.text:00000001400145B0 var_18 = qword ptr -18h
.text:00000001400145B0
.text:00000001400145B0 sub rsp, 38h
.text:00000001400145B4 mov rax, 2B992DDFA232h
.text:00000001400145BE cmp cs:__security_cookie, rax
.text:00000001400145C5 jz short loc_1400145DA
.text:00000001400145C7 mov rax, cs:__security_cookie
.text:00000001400145CE not rax
.text:00000001400145D1 mov cs:qword_14001E080, rax
.text:00000001400145D8 jmp short loc_14001461F
.text:00000001400145DA
.text:00000001400145DA loc_1400145DA: ; CODE XREF: sub_1400145B0+15↑j
.text:00000001400145DA call sub_1400144C0
.text:00000001400145DF mov [rsp+38h+var_18], rax
.text:00000001400145E4 mov rax, 2B992DDFA232h
.text:00000001400145EE cmp [rsp+38h+var_18], rax
.text:00000001400145F3 jnz short loc_140014604
.text:00000001400145F5 mov rax, 2B992DDFA233h
.text:00000001400145FF mov [rsp+38h+var_18], rax
.text:0000000140014604
.text:0000000140014604 loc_140014604: ; CODE XREF: sub_1400145B0+43↑j
.text:0000000140014604 mov rax, [rsp+38h+var_18]
.text:0000000140014609 mov cs:__security_cookie, rax
.text:0000000140014610 mov rax, [rsp+38h+var_18]
.text:0000000140014615 not rax
.text:0000000140014618 mov cs:qword_14001E080, rax
.text:000000014001461F
.text:000000014001461F loc_14001461F:
.text:000000014001461F add rsp, 38h
.text:0000000140014623 retn`

本次评测参与的模型有:

模型 文心一言 通义千问 ChatGPT3.5
版本 2.5.2 2.1.1 text-davinci-002-render-sha

对比大模型的反编译能力

文心一言的表现

image-20231227202743069

通义千问的表现

image-20231227202836898

ChatGPT3.5的表现

image-20231227203058570

结果

首先,分析我们的任务要求。我们的任务要求包括三部分,一是对汇编代码的进行提升,二是总结代码功能,三是推测函数的来源,细节上我们还要求“用少于等于100字”进行归纳总结。

三个模型的完成情况如下(-表示没有识别到任务,0表示未完成,0.5表示完成的一般,1表示基本完成):

文心一言 通义千问 ChatGPT3.5
提升 - - 0
总结 1 1 1
推测 - 0.5 0.5
100字内 1 1 1

三个模型基本都能做到对代码的总结(虽然接近对汇编代码的逐行翻译了),也能控制字数在指定范围内,但两个国产模型没有识别到提升任务,此外文心一言还没有完成推测任务。可能由于信息缺失,导致推测任务对于大模型而言比较困难,所以我进行了补充信息的尝试,补充的信息如下:

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
接下来我将补充关于函数sub_1400144C0的内容。补充完全后,你需要重新分析sub_1400145B0函数。
.text:1400144C0 sub_1400144C0 proc near
.text:1400144C0 push rdi
.text:1400144C2 sub rsp, 40h
.text:1400144C6 lea rax, [rsp+48h+SystemTimeAsFileTime]
.text:1400144CB mov rdi, rax
.text:1400144CE xor eax, eax
.text:1400144D0 mov ecx, 8
.text:1400144D5 rep stosb
.text:1400144D7 lea rcx, [rsp+48h+SystemTimeAsFileTime]
.text:1400144DC call cs:GetSystemTimeAsFileTime
.text:1400144E2 mov rax, qword ptr [rsp+48h+SystemTimeAsFileTime.dwLowDateTime]
.text:1400144E7 mov [rsp+48h+var_28], rax
.text:1400144EC call cs:GetCurrentThreadId
.text:1400144F2 mov eax, eax
.text:1400144F4 mov rcx, [rsp+48h+var_28]
.text:1400144F9 xor rcx, rax
.text:1400144FC mov rax, rcx
.text:1400144FF mov [rsp+48h+var_28], rax
.text:140014504 call cs:GetCurrentProcessId
.text:14001450A mov eax, eax
.text:14001450C mov rcx, [rsp+48h+var_28]
.text:140014511 xor rcx, rax
.text:140014514 mov rax, rcx
.text:140014517 mov [rsp+48h+var_28], rax
.text:14001451C lea rcx, [rsp+48h+PerformanceCount]
.text:140014521 call cs:QueryPerformanceCounter
.text:140014527 mov eax, dword ptr [rsp+48h+PerformanceCount]
.text:14001452B shl rax, 20h
.text:14001452F xor rax, qword ptr [rsp+48h+PerformanceCount]
.text:140014534 mov rcx, [rsp+48h+var_28]
.text:140014539 xor rcx, rax
.text:14001453C mov rax, rcx
.text:14001453F mov [rsp+48h+var_28], rax
.text:140014544 lea rax, [rsp+48h+var_28]
.text:140014549 mov rcx, [rsp+48h+var_28]
.text:14001454E xor rcx, rax
.text:140014551 mov rax, rcx
.text:140014554 mov [rsp+48h+var_28], rax
.text:140014559 mov rax, 0FFFFFFFFFFFFh
.text:140014563 mov rcx, [rsp+48h+var_28]
.text:140014568 and rcx, rax
.text:14001456B mov rax, rcx
.text:14001456E mov [rsp+48h+var_28], rax
.text:140014573 mov rax, [rsp+48h+var_28]
.text:140014578 add rsp, 40h
.text:14001457C pop rdi
.text:14001457D retn

囿于篇幅,不展示具体的结果仅作口头描述。

三个模型均首先提升了新补充的函数,并没有重新分析目标函数,总结功能上更加具体了一些,但仍不能推测函数的出处,需要指出的是ChatGPT的没有真正提升至高级语言。

对比不同大模型的推测分析能力

在本part中,我尝试直接提供ida pro反编译的结果给大模型,让他们重新分析,promot与上一个实验一致。

提供的反编译代码如下:

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
unsigned __int64 sub_1400144C0()
{
unsigned __int64 v1; // [rsp+20h] [rbp-28h] BYREF
struct _FILETIME SystemTimeAsFileTime; // [rsp+28h] [rbp-20h] BYREF
LARGE_INTEGER PerformanceCount; // [rsp+30h] [rbp-18h] BYREF

memset(&SystemTimeAsFileTime, 0, sizeof(SystemTimeAsFileTime));
GetSystemTimeAsFileTime(&SystemTimeAsFileTime);
v1 = (unsigned __int64)SystemTimeAsFileTime;
v1 ^= GetCurrentThreadId();
v1 ^= GetCurrentProcessId();
QueryPerformanceCounter(&PerformanceCount);
return ((unsigned __int64)&v1 ^ PerformanceCount.QuadPart ^ ((unsigned __int64)PerformanceCount.LowPart << 32) ^ v1) & 0xFFFFFFFFFFFFi64;
}
uintptr_t sub_1400145B0()
{
uintptr_t result; // rax
unsigned __int64 v1; // [rsp+20h] [rbp-18h]

if ( _security_cookie == 0x2B992DDFA232i64 )
{
v1 = sub_1400144C0();
if ( v1 == 0x2B992DDFA232i64 )
v1 = 0x2B992DDFA233i64;
_security_cookie = v1;
result = ~v1;
qword_14001E080 = ~v1;
}
else
{
result = ~_security_cookie;
qword_14001E080 = ~_security_cookie;
}
return result;
}

文心一言的表现

image-20231227221124047

通义千问的表现

image-20231227221119523

ChatGPT3.5的表现

image-20231227222043631

结果

三个模型的完成情况如下(-表示没有识别到任务,0表示未完成,0.5表示完成的一般,1表示基本完成):

文心一言 通义千问 ChatGPT3.5
总结 1 0.5 1
推测 0 1 0.5

三个模型的表现各有亮点,文心一言和ChatGPT3.5都在总结中指出了函数用于防御缓冲区溢出;在预测部分中,通义千问给出了函数名(实际查询后发现给出的函数名是错误的,但有一定参考价值),而ChatGPT注意到了该函数和Windows相关。

以WPeChatGPT插件为例,对比不同提示的效果

通过阅读WPeChatGPT的源码,我将其逆向部分使用的Promot提取如下(原插件中还设计了漏洞分析和利用的promot)

1
2
3
下面是一个C语言伪代码函数,分别分析该函数的预期目的、参数的作用、详细功能,最后取一个新的函数名字。(用简体中文回答我,并且回答开始前加上'---GPT_START---'字符串结束后加上'---GPT_END---'字符串
结合该程序的函数调用结构及其所包含的字符串,猜测其运行目的及功能。
请再仔细分析后告诉我该程序的运行目的及大概功能。

这个提示包括两部分,第一部分是逐步分析,第二部分是总结(反复确认是为了减少错误)。

让我发送测试中的伪C代码,以下是Chat-GPT3.5 Turbo的响应

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
# PART 1
---GPT_START---
这段C语言伪代码实际上是两个函数的定义,我们分别来分析它们的预期目的、参数的作用以及详细功能。

第一个函数(sub_1400144C0)的预期目的:
该函数的预期目的是生成一个无符号整数作为随机数或者用作特定目的的标识符。

参数的作用:
该函数没有任何参数。

详细功能:

创建一个无符号整数变量 v1,并初始化为 0。
使用 GetSystemTimeAsFileTime 函数获取当前系统时间,并将其存储在 SystemTimeAsFileTime 结构体中。
将 SystemTimeAsFileTime 的值转换为无符号整数,并存储在 v1 中。
对 v1 进行位异或操作,依次与当前线程 ID 和当前进程 ID 进行异或操作。
使用 QueryPerformanceCounter 函数获取性能计数器的值,并将其存储在 PerformanceCount 变量中。
将 v1 与 PerformanceCount.QuadPart 进行位异或操作,然后将 PerformanceCount.LowPart 左移 32 位与其异或,再将 v1 与结果进行异或。
将结果与 0xFFFFFFFFFFFF 进行位与操作,以保留低 48 位的值。
返回结果作为函数的输出。
第二个函数(sub_1400145B0)的预期目的:
该函数的预期目的是生成一个安全的随机数或者用作特定目的的标识符,并更新安全 cookie 的值。

参数的作用:
该函数没有任何参数。

详细功能:

检查全局变量 _security_cookie 的值是否等于 0x2B992DDFA232i64。
如果 _security_cookie 的值等于 0x2B992DDFA232i64,则执行以下步骤:
调用 sub_1400144C0 函数获取一个随机数或标识符,并将其存储在 v1 中。
如果 v1 的值等于 0x2B992DDFA232i64,则将其更新为 0x2B992DDFA233i64。
将 v1 的值赋给 _security_cookie 和 qword_14001E080。
将 v1 的按位取反作为函数的返回值。
如果 _security_cookie 的值不等于 0x2B992DDFA232i64,则将 _security_cookie 的按位取反赋给 result 和 qword_14001E080。
返回 result 作为函数的输出。
根据这两个函数的功能,可以将第一个函数命名为 generateRandomIdentifier,将第二个函数命名为 updateSecurityCookie。

---GPT_END---

# PART 2
过进一步分析,我可以给出更准确的关于该程序的运行目的和大概功能的推测。

该程序的运行目的:
该程序的运行目的是生成一个安全的随机数或标识符,用于加强程序的安全性和防止恶意攻击,特别是针对缓冲区溢出等安全漏洞的攻击。

该程序的大概功能:

sub_1400144C0 函数用于生成一个随机数或标识符。

首先,该函数获取当前系统时间,并将其转换为一个无符号整数。
然后,与当前线程 ID 和当前进程 ID 进行异或运算,以增加随机性。
最后,使用性能计数器的值进行一系列位异或操作,并将生成的随机数或标识符返回。
sub_1400145B0 函数用于更新安全 cookie 的值。

首先,该函数检查全局变量 _security_cookie 的值是否等于特定的常量(0x2B992DDFA232i64)来验证安全性。
如果 _security_cookie 的值等于特定常量,则调用 sub_1400144C0 函数生成一个新的随机数或标识符,并将其赋给 _security_cookie 和另一个全局变量 qword_14001E080。
如果 _security_cookie 的值不等于特定常量,则将 _security_cookie 按位取反,并赋给 result 和 qword_14001E080。
综上所述,该程序的大概功能是生成用于加强程序安全性的随机数或标识符,并通过更新安全 cookie 的值来保护程序免受潜在的攻击。这种机制可以增加程序的安全性,防止某些类型的攻击,如缓冲区溢出。但具体的功能和用途仍需要查看完整的源代码或相关文档以进行确认。

可能是由于目标代码比较简单,并没有比较出明显差距。但WPeChatGPT所使用的提示也启发了我们:

  1. 还应该让大模型关注参数和返回值
  2. 逐步完成任务,先仔细分析,再综合分析。

总结

  1. 大模型在逆向任务中大有用处,但也存在能力边界

    1. 大模型目前不能帮助我们完成反编译工作,IDA Pro这样的专业逆向工具还是非常强力的。

    2. 大模型具有丰富的知识,其在函数名恢复和函数库推测上有优势。

    3. 大模型对函数功能的总结可以帮助我们快速理解函数功能或对我们的猜测工作给予指引,这将节省我们非常多的时间。

  2. 合理设计Promot‘

    1. 让模型扮演一个角色
    2. 指引大模型分步骤完成任务
    3. 设计良好的格式
    4. 补充必要的知识/上下文:在使用时应该提供伪C代码并尽量补充涉及的函数的实现。
  3. 逆向任务中ChatGPT3.5 > 通义千问 > 文心一言