首页
社区
课程
招聘
[原创]KCTF 2025 第五题 智破幻阵wp
发表于: 2025-8-23 17:07 4747

[原创]KCTF 2025 第五题 智破幻阵wp

2025-8-23 17:07
4747

放进ida, 从程序入口开始分析:

看到它将函数sub_140115000添加为异常处理函数, 然后调用了sub_140001000;
sub_140001000中主要行为是创建窗口,以及创建了一个线程入口点为sub_140001FB0;
此后sub_140115000sub_140001FB0点进去看都是一串mov.

此时对开始学习硬刚movfuscator还有一些犹豫, 先再整体观察一下这个程序;
观察到sub_140115000sub_140001FB0分别在段.zx3与段.zx1, 打开Segments看到特殊段有.zx0 .zx1 .zx2 .zx3:

.zx0 看起来为数据段;
.zx1 是代码段, 点进去也是一串mov, 滑几下滚轮看到了一个常数:

搜索一下就知道是sha256的常数,而且题目给的序列号的长度与sha256结果长度相同(后来发现是偶然),可以认为验证过程一定用到了sha256函数,且.zx1段首地址1400A9000应该就是sha256函数的入口;
.zx2 是代码段, 点进去观察到段首代码引用了.zx0的地址, 再观察一下.zx0的数据看到一堆或整齐或错位的0到255;
.zx3 也是代码段但是段首有一溜.zx2的地址,疑似一些函数的入口点;同时用来查找库函数的代码也在.zx3.
之后考虑先动态调试寻找一下sha256的入参, 发现windbg不能用, 但是frida能用;
顺便在脚本同目录运行pnpm i @types/frida-gum可以在写脚本时具有类型提示.
观察到sha256入口处保存了rcx,rdx,r8,r9,
先写frida脚本如下:

运行 frida ./zx_mov_obfu.exe -l i.js -o i.log 填入示例用户名序列号, 输出为

发现sha256的参数为用户名;
但是之后也没法跟, 只能先看看movfuscator.
阅读 756K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6^5L8%4u0W2j5i4S2W2j5i4S2W2j5i4S2Q4x3V1k6E0L8%4k6X3N6i4y4U0j5i4c8G2M7R3`.`. 了解到movfuscator的运算主要通过查表, 以异或为例:

所以之前观察到的.zx3存放.zx2函数地址, .zx2函数引用.zx0.zx0中保存着各种运算表, .zx3存放的.zx2函数们应该负责各种运算;
如果所有运算操作都由这些函数完成, 则可以通过hook这些函数并输出完整的运算步骤来分析算法.
接下来的任务是判断这些函数的参数保存位置以及负责什么运算;
通过分析.zx0中的数据可以看出:

接下来分析函数功能有两种方式, 一是静态观察函数使用了什么运算表, 二是重点分析函数头尾的数据流, 找出入参与返回值的位置, 然后hook并输出它们来看是什么运算.
在分析过程中观察到在mov rax fs/gs:...前的代码:

有很多都将其后的代码地址存于1400061f0, 则该处很有可能保存着返回地址.

之后以sha256(59A35804E4F4C235)的结果60c5ef828d8be31ec6f2968436887a864e5020488dcf95e657fc9eb009870113为基点, 在输出文件i.log中查找, 能够找到:(其中step1输出是找到并分析后添加的)

这段代码再对sha256(name)的结果串做分解, 跳转到其中and的返回地址0x1400b8e97, 注意之前能分析出其返回值保存于0x140006098:

and操作的返回值被存入[rsp+rcx*4+2F0h], hook此处并添加step1输出可以确认其逻辑:

同时在ida中搜索+2F0h可以找到:

hook并确认写入位置:

用python重写:

之后的运算:

在算(23333*114514)+1919810之后循环*114514+1919810...搜索0x1d4b42看到共乘加了28次最后得到了个常数0xd4abe55e. 既然是常数其实可以不管它, 在之后的运算它仍会以常数形式出现.
再之后的运算为:

看到在处理0x5e67f37f, 而0x5e67f37f是示例序列号7FF3675E036335E65E5D29D121FC149197556E6EA39F2E1A1A05437A9609EBC2的小端序第一个32位数字;
并看到其中有cmp: 0x0 0x1a0a false0x1a0a正是step1中被添加到结果末尾的数字, 在log中搜索0x1400baa2a发现有多达1032个结果, 观察发现cmp的第一个参数正是按顺序出现的step1的结果, 每轮出现8次, 且只能为0 1 2 3 0x1a0a中的一种, 判断为0x1a0a应表示循环结束.
之后分别搜索cmp: 0x0 0x1a0a,cmp: 0x1 0x1a0a,cmp: 0x2 0x1a0a,cmp: 0x3 0x1a0a发现其后进行的运算由cmp的第一个参数决定:

0 1 2的对应运算比较好写, 3的对应运算还涉及到0x1400bd11a add: 0x1 0x1 0x2的结果值会作为其后移位运算的计算次数, 需要跟踪此处add的参数及其来源; 搜索0x1400bd11a可以发现 第二个参数总为1, 重点是第一个参数从哪来:

发现从[rsp+9Ch]中来, 在ida中搜索+9Ch可以找到:

这里静态不太好跟, 于是下个hook观察一下:

可以观察出该处的值为示例序列号作为小端序32位整数数组中被操作的值的下标.
于是可以写出step2:

再写出reverse_step2:

之后观察step2的结果, 发现是全0:

即可拼出完整的求用户KCTF序列号的算法:

__int64 start()
{
  __int64 v0; // rax
  __int64 v1; // rax
  __int64 v2; // rax
  __int64 v3; // rax
  char v5[16]; // [rsp+20h] [rbp-C8h] BYREF
  char v6[16]; // [rsp+30h] [rbp-B8h] BYREF
  char v7[16]; // [rsp+40h] [rbp-A8h] BYREF
  char v8[32]; // [rsp+50h] [rbp-98h] BYREF
  char v9[32]; // [rsp+70h] [rbp-78h] BYREF
  __int64 v10; // [rsp+90h] [rbp-58h]
  __int64 (__fastcall *VirtualAlloc)(_QWORD, __int64, __int64, __int64); // [rsp+98h] [rbp-50h]
  _QWORD *p1400061E8; // [rsp+A0h] [rbp-48h]
  __int64 v13; // [rsp+A8h] [rbp-40h]
  __int64 (__fastcall *AddVectoredExceptionHandler)(__int64, __int64); // [rsp+B0h] [rbp-38h]
  void (*windfn)(void); // [rsp+B8h] [rbp-30h]
  void (*v16)(void); // [rsp+C0h] [rbp-28h]
  __int64 v17; // [rsp+C8h] [rbp-20h]
  void (__fastcall *RemoveVectoredExceptionHandler)(__int64); // [rsp+D0h] [rbp-18h]
  void (__fastcall *VirtualFree)(__int64, _QWORD, __int64); // [rsp+D8h] [rbp-10h]
 
  windfn = (void (*)(void))sub_140001000;
  v13 = 0x140115000LL;
  p1400061E8 = (_QWORD *)&qword_1400061E8;
  v10 = 0LL;
  strcpy(v5, "kernel32.dll");
  strcpy(v8, "AddVectoredExceptionHandler");
  strcpy(v9, "RemoveVectoredExceptionHandler");
  strcpy(v7, "VirtualAlloc");
  strcpy(v6, "VirtualFree");
  v0 = sub_1401141D0(v5);
  AddVectoredExceptionHandler = (__int64 (__fastcall *)(__int64, __int64))sub_1401143C0(v0, v8);
  v1 = sub_1401141D0(v5);
  RemoveVectoredExceptionHandler = (void (__fastcall *)(__int64))sub_1401143C0(v1, v9);
  v2 = sub_1401141D0(v5);
  VirtualAlloc = (__int64 (__fastcall *)(_QWORD, __int64, __int64, __int64))sub_1401143C0(v2, v7);
  v3 = sub_1401141D0(v5);
  VirtualFree = (void (__fastcall *)(__int64, _QWORD, __int64))sub_1401143C0(v3, v6);
  v10 = VirtualAlloc(0LL, 0x10000LL, 0x1000LL, 4LL);
  *p1400061E8 = v10 + 0xFFF8;
  v17 = AddVectoredExceptionHandler(1LL, v13);
  v16 = windfn;
  windfn();
  RemoveVectoredExceptionHandler(v17);
  VirtualFree(v10, 0LL, 0x8000LL);
  return 0LL;
}
__int64 start()
{
  __int64 v0; // rax
  __int64 v1; // rax
  __int64 v2; // rax
  __int64 v3; // rax
  char v5[16]; // [rsp+20h] [rbp-C8h] BYREF
  char v6[16]; // [rsp+30h] [rbp-B8h] BYREF
  char v7[16]; // [rsp+40h] [rbp-A8h] BYREF
  char v8[32]; // [rsp+50h] [rbp-98h] BYREF
  char v9[32]; // [rsp+70h] [rbp-78h] BYREF
  __int64 v10; // [rsp+90h] [rbp-58h]
  __int64 (__fastcall *VirtualAlloc)(_QWORD, __int64, __int64, __int64); // [rsp+98h] [rbp-50h]
  _QWORD *p1400061E8; // [rsp+A0h] [rbp-48h]
  __int64 v13; // [rsp+A8h] [rbp-40h]
  __int64 (__fastcall *AddVectoredExceptionHandler)(__int64, __int64); // [rsp+B0h] [rbp-38h]
  void (*windfn)(void); // [rsp+B8h] [rbp-30h]
  void (*v16)(void); // [rsp+C0h] [rbp-28h]
  __int64 v17; // [rsp+C8h] [rbp-20h]
  void (__fastcall *RemoveVectoredExceptionHandler)(__int64); // [rsp+D0h] [rbp-18h]
  void (__fastcall *VirtualFree)(__int64, _QWORD, __int64); // [rsp+D8h] [rbp-10h]
 
  windfn = (void (*)(void))sub_140001000;
  v13 = 0x140115000LL;
  p1400061E8 = (_QWORD *)&qword_1400061E8;
  v10 = 0LL;
  strcpy(v5, "kernel32.dll");
  strcpy(v8, "AddVectoredExceptionHandler");
  strcpy(v9, "RemoveVectoredExceptionHandler");
  strcpy(v7, "VirtualAlloc");
  strcpy(v6, "VirtualFree");
  v0 = sub_1401141D0(v5);
  AddVectoredExceptionHandler = (__int64 (__fastcall *)(__int64, __int64))sub_1401143C0(v0, v8);
  v1 = sub_1401141D0(v5);
  RemoveVectoredExceptionHandler = (void (__fastcall *)(__int64))sub_1401143C0(v1, v9);
  v2 = sub_1401141D0(v5);
  VirtualAlloc = (__int64 (__fastcall *)(_QWORD, __int64, __int64, __int64))sub_1401143C0(v2, v7);
  v3 = sub_1401141D0(v5);
  VirtualFree = (void (__fastcall *)(__int64, _QWORD, __int64))sub_1401143C0(v3, v6);
  v10 = VirtualAlloc(0LL, 0x10000LL, 0x1000LL, 4LL);
  *p1400061E8 = v10 + 0xFFF8;
  v17 = AddVectoredExceptionHandler(1LL, v13);
  v16 = windfn;
  windfn();
  RemoveVectoredExceptionHandler(v17);
  VirtualFree(v10, 0LL, 0x8000LL);
  return 0LL;
}
// i.js
Interceptor.attach(ptr(0x1400A9000), function sha_cb() {
    console.log("sha", this.context.rsp, this.context.rcx, this.context.rdx, this.context.r8, this.context.r9);
    // 观察到rcx rdx类似指针 r8为0x10后添加hexdump
    console.log(hexdump(ptr(this.context.rcx), {length: 0x20}));
    console.log(hexdump(ptr(this.context.rdx), {length: 0x20}));
});
// i.js
Interceptor.attach(ptr(0x1400A9000), function sha_cb() {
    console.log("sha", this.context.rsp, this.context.rcx, this.context.rdx, this.context.r8, this.context.r9);
    // 观察到rcx rdx类似指针 r8为0x10后添加hexdump
    console.log(hexdump(ptr(this.context.rcx), {length: 0x20}));
    console.log(hexdump(ptr(this.context.rdx), {length: 0x20}));
});
sha 0x6cdf8a8 0x6cdfdb0 0x6cdf9b0 0x10 0x6cdf9c0
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
06cdfdb0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
06cdfdc0  00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 80  ................
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
06cdf9b0  35 39 41 33 35 38 30 34 45 34 46 34 43 32 33 35  59A35804E4F4C235
06cdf9c0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
sha 0x6cdf8a8 0x6cdfdb0 0x6cdf9b0 0x10 0x6cdf9c0
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
06cdfdb0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
06cdfdc0  00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 80  ................
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
06cdf9b0  35 39 41 33 35 38 30 34 45 34 46 34 43 32 33 35  59A35804E4F4C235
06cdf9c0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
// movfuscator/movfuscator.c
#define BUILD_2D_TABLE(name, e_size, height, width, expr) \
    { \
        int X, Y; \
        print(".align 16\n"); \
        print(".globl %s\n", (name)); \
        print("%s: .long ", (name)); \
        for (X=0; X<(height); X++) { \
            print("%s_%d,", (name), X); \
        } \
        print("END\n"); \
        \
        for (X=0; X<height; X++) { \
            print(".globl %s_%d\n", (name), X); \
            print("%s_%d: .%s ", (name), X, e_size); \
            for (Y=0; Y<width; Y++) print("0x%x,",(expr)); \
            print("END\n"); \
        } \
        print("\n"); \
    }
 
// 此处建立256*256大小的x^y的结果表
BUILD_2D_TABLE("alu_bxor8""byte", 256, 256, (X^Y)&0xff);
 
static void alu_bxor32(char* s, char* x, char* y)
{
    print("# alu_bxor32\n");
    debug_id();
    alu_bxor8(s, x, y, 0);
    alu_bxor8(s, x, y, 1);
    alu_bxor8(s, x, y, 2);
    alu_bxor8(s, x, y, 3);
    print("# end alu_bxor32\n");
}
 
static void alu_bxor8(char* s, char* x, char* y, int off)
{
    print("# alu_bxor8\n");
    debug_id();
    print("movl $0, %%eax\n");
    print("movl $0, %%edx\n");
    print("movb (%s+%d), %%al\n", x, off);
    print("movb (%s+%d), %%dl\n", y, off);
    print("movl alu_bxor8(,%%eax,4), %%eax\n");
    print("movb (%%eax,%%edx), %%al\n");
    print("movb %%al, (%s+%d)\n", s, off);
    print("# end alu_bxor8\n");
}
// movfuscator/movfuscator.c
#define BUILD_2D_TABLE(name, e_size, height, width, expr) \
    { \
        int X, Y; \
        print(".align 16\n"); \
        print(".globl %s\n", (name)); \
        print("%s: .long ", (name)); \
        for (X=0; X<(height); X++) { \
            print("%s_%d,", (name), X); \
        } \
        print("END\n"); \
        \
        for (X=0; X<height; X++) { \
            print(".globl %s_%d\n", (name), X); \
            print("%s_%d: .%s ", (name), X, e_size); \
            for (Y=0; Y<width; Y++) print("0x%x,",(expr)); \
            print("END\n"); \
        } \
        print("\n"); \
    }
 
// 此处建立256*256大小的x^y的结果表
BUILD_2D_TABLE("alu_bxor8""byte", 256, 256, (X^Y)&0xff);
 
static void alu_bxor32(char* s, char* x, char* y)
{
    print("# alu_bxor32\n");
    debug_id();
    alu_bxor8(s, x, y, 0);
    alu_bxor8(s, x, y, 1);
    alu_bxor8(s, x, y, 2);
    alu_bxor8(s, x, y, 3);
    print("# end alu_bxor32\n");
}
 
static void alu_bxor8(char* s, char* x, char* y, int off)
{
    print("# alu_bxor8\n");
    debug_id();
    print("movl $0, %%eax\n");
    print("movl $0, %%edx\n");
    print("movb (%s+%d), %%al\n", x, off);
    print("movb (%s+%d), %%dl\n", y, off);
    print("movl alu_bxor8(,%%eax,4), %%eax\n");
    print("movb (%%eax,%%edx), %%al\n");
    print("movb %%al, (%s+%d)\n", s, off);
    print("# end alu_bxor8\n");
}
2d_tbl_size=0x200*0x100=0x20000
tbl_add = zx0base+0x200   # 140006200
tbl_mul = zx0base+0x20200 # 140026200
tbl_and = zx0base+0x40200 # 140046200
tbl_or  = zx0base+0x60200 # 140066200
tbl_xor = zx0base+0x80200 # 140086200
tbl_true= zx0base+0xa1200 # 1400A7200
2d_tbl_size=0x200*0x100=0x20000
tbl_add = zx0base+0x200   # 140006200
tbl_mul = zx0base+0x20200 # 140026200
tbl_and = zx0base+0x40200 # 140046200
tbl_or  = zx0base+0x60200 # 140066200
tbl_xor = zx0base+0x80200 # 140086200
tbl_true= zx0base+0xa1200 # 1400A7200
.zx1:00000001400B8ECB                 mov     r14, 140000000h
.zx1:00000001400B8ED5                 mov     [r14+60E0h], rcx
.zx1:00000001400B8EDC                 mov     ecx, eax
.zx1:00000001400B8EDE                 mov     qword ptr [r14+6088h], 0
.zx1:00000001400B8EE9                 mov     [r14+6088h], ecx
.zx1:00000001400B8EF0                 mov     rcx, [r14+60E0h]
.zx1:00000001400B8EF7                 mov     [r14+60E0h], rax
.zx1:00000001400B8EFE                 mov     rax, 1400B8F2Ch
.zx1:00000001400B8F08                 mov     [r14+61F0h], rax
.zx1:00000001400B8F0F                 mov     rax, [r14+60E0h]
.zx1:00000001400B8F16                 mov     rax, fs:6603000000000000h
.zx1:00000001400B8F21                 mov     rax, gs:6600000000000004h
.zx1:00000001400B8F2C                 mov     [r14+60E0h], rcx
.zx1:00000001400B8ECB                 mov     r14, 140000000h
.zx1:00000001400B8ED5                 mov     [r14+60E0h], rcx
.zx1:00000001400B8EDC                 mov     ecx, eax
.zx1:00000001400B8EDE                 mov     qword ptr [r14+6088h], 0
.zx1:00000001400B8EE9                 mov     [r14+6088h], ecx
.zx1:00000001400B8EF0                 mov     rcx, [r14+60E0h]
.zx1:00000001400B8EF7                 mov     [r14+60E0h], rax
.zx1:00000001400B8EFE                 mov     rax, 1400B8F2Ch
.zx1:00000001400B8F08                 mov     [r14+61F0h], rax
.zx1:00000001400B8F0F                 mov     rax, [r14+60E0h]
.zx1:00000001400B8F16                 mov     rax, fs:6603000000000000h
.zx1:00000001400B8F21                 mov     rax, gs:6600000000000004h
.zx1:00000001400B8F2C                 mov     [r14+60E0h], rcx
// 59A35804E4F4C235
// 7FF3675E036335E65E5D29D121FC149197556E6EA39F2E1A1A05437A9609EBC2
 
/**
 * @this {InvocationContext}
*/
function unknown_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'unknown 4:', arg1, arg2);
}
/**
 * @this {InvocationContext}
*/
function unknown_ret_cb() {
    const result = ptr(0x140006098).readPointer();
    const result2 = ptr(0x1400060c0).readPointer();
    console.log('unknown result:', result, result2);
}
 
Interceptor.attach(ptr(0x1400A9000), function sha_cb() {
    console.log("sha", this.context.rsp, this.context.rcx, this.context.rdx, this.context.r8, this.context.r9);
    console.log(hexdump(ptr(this.context.rcx), {length: 0x20}));
    console.log(hexdump(ptr(this.context.rdx), {length: 0x20}));
});
// idx 0x0
Interceptor.attach(ptr(0x1400C6000), function xor_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'xor:', arg1, arg2, arg1.xor(arg2));
});
// idx 0x1
Interceptor.attach(ptr(0x1400C6727), function and_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'and:', arg1, arg2, arg1.and(arg2));
});
// idx 0x2
Interceptor.attach(ptr(0x1400C6e4e), function or_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'or:', arg1, arg2, arg1.or(arg2));
});
// idx 0x3
Interceptor.attach(ptr(0x1400C7575), function inv_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    console.log(raddr, 'inv:', arg1, arg1.not().and(0xffffffff));
});
// idx 0x4
Interceptor.attach(ptr(0x1400C7AC0), function add_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'add:', arg1, arg2, arg1.add(arg2));
});
// idx 0xf
Interceptor.attach(ptr(0x1400CFABB), function sub_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'sub/cmp:', arg1, arg2, arg1.equals(arg2));
});
 
// idx 0x11
Interceptor.attach(ptr(0x1400E079D), function mul_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = BigInt(ptr(0x140006088).readU64());
    const arg2 = BigInt(ptr(0x140006090).readU64());
    console.log(raddr, 'mul:', '0x'+arg1.toString(16), '0x'+arg2.toString(16), '0x'+(((arg1*arg2)&0xffffffffn).toString(16)));
});
// idx 0x13
Interceptor.attach(ptr(0x1400F4B41), function add2_cb() { // 13
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'add2:', arg1, arg2, arg1.add(arg2));
});
// idx 0x15
Interceptor.attach(ptr(0x1400F6BC1), function shr_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer().and(0xff);
    console.log(raddr, 'shr:', arg1, arg2, arg1.shr(arg2));
});
// idx 0x16
Interceptor.attach(ptr(0x1400F7CA3), function shl_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'shl:', arg1, arg2, arg1.shl(arg2));
});
// idx 0x2a
Interceptor.attach(ptr(0x1401121EC), function xorb_cb(ctx, args) {
    ctx = this;
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x1400060a8).readPointer();
    const arg2 = ptr(0x1400060b0).readPointer();
    console.log(raddr, 'xorb:', arg1, arg2, arg1.xor(arg2));
});
// idx 0x2b
Interceptor.attach(ptr(0x14011229B), function xor3_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x1400060a8).readPointer();
    const arg2 = ptr(0x1400060b0).readPointer();
    const arg3 = ptr(0x1400060b8).readPointer();
    console.log(raddr, 'xor3:', arg1, arg2, arg3, arg1.xor(arg2).xor(arg3));
});
Interceptor.attach(ptr(0x1400B8EB9), function step1_cb() {
    console.log('step1', this.context.rcx, this.context.rax);
});
Interceptor.attach(ptr(0x1400B920E), function() {
    console.log("step1 write 1a0a to idx", this.context.rax)
});
 
// Interceptor.attach(ptr(0x1400C8BD8), unknown_cb);
 
let tn = 5;
Interceptor.attach(ptr(0x1400B18F4), function() {
    const rax = ptr(this.context.rax);
    console.log("from:", rax, rax.add(0x20).readU32());
    if(tn > 0) {
        console.log(hexdump(rax, {length:0x40}));
        tn -= 1;
    }
});
 
console.log('reloaded')
// 59A35804E4F4C235
// 7FF3675E036335E65E5D29D121FC149197556E6EA39F2E1A1A05437A9609EBC2
 
/**
 * @this {InvocationContext}
*/
function unknown_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'unknown 4:', arg1, arg2);
}
/**
 * @this {InvocationContext}
*/
function unknown_ret_cb() {
    const result = ptr(0x140006098).readPointer();
    const result2 = ptr(0x1400060c0).readPointer();
    console.log('unknown result:', result, result2);
}
 
Interceptor.attach(ptr(0x1400A9000), function sha_cb() {
    console.log("sha", this.context.rsp, this.context.rcx, this.context.rdx, this.context.r8, this.context.r9);
    console.log(hexdump(ptr(this.context.rcx), {length: 0x20}));
    console.log(hexdump(ptr(this.context.rdx), {length: 0x20}));
});
// idx 0x0
Interceptor.attach(ptr(0x1400C6000), function xor_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'xor:', arg1, arg2, arg1.xor(arg2));
});
// idx 0x1
Interceptor.attach(ptr(0x1400C6727), function and_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'and:', arg1, arg2, arg1.and(arg2));
});
// idx 0x2
Interceptor.attach(ptr(0x1400C6e4e), function or_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'or:', arg1, arg2, arg1.or(arg2));
});
// idx 0x3
Interceptor.attach(ptr(0x1400C7575), function inv_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    console.log(raddr, 'inv:', arg1, arg1.not().and(0xffffffff));
});
// idx 0x4
Interceptor.attach(ptr(0x1400C7AC0), function add_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'add:', arg1, arg2, arg1.add(arg2));
});
// idx 0xf
Interceptor.attach(ptr(0x1400CFABB), function sub_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'sub/cmp:', arg1, arg2, arg1.equals(arg2));
});
 
// idx 0x11
Interceptor.attach(ptr(0x1400E079D), function mul_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = BigInt(ptr(0x140006088).readU64());
    const arg2 = BigInt(ptr(0x140006090).readU64());
    console.log(raddr, 'mul:', '0x'+arg1.toString(16), '0x'+arg2.toString(16), '0x'+(((arg1*arg2)&0xffffffffn).toString(16)));
});
// idx 0x13
Interceptor.attach(ptr(0x1400F4B41), function add2_cb() { // 13
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'add2:', arg1, arg2, arg1.add(arg2));
});
// idx 0x15
Interceptor.attach(ptr(0x1400F6BC1), function shr_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer().and(0xff);
    console.log(raddr, 'shr:', arg1, arg2, arg1.shr(arg2));
});
// idx 0x16
Interceptor.attach(ptr(0x1400F7CA3), function shl_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x140006088).readPointer();
    const arg2 = ptr(0x140006090).readPointer();
    console.log(raddr, 'shl:', arg1, arg2, arg1.shl(arg2));
});
// idx 0x2a
Interceptor.attach(ptr(0x1401121EC), function xorb_cb(ctx, args) {
    ctx = this;
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x1400060a8).readPointer();
    const arg2 = ptr(0x1400060b0).readPointer();
    console.log(raddr, 'xorb:', arg1, arg2, arg1.xor(arg2));
});
// idx 0x2b
Interceptor.attach(ptr(0x14011229B), function xor3_cb() {
    const raddr = ptr(0x1400061F0).readPointer();
    const arg1 = ptr(0x1400060a8).readPointer();
    const arg2 = ptr(0x1400060b0).readPointer();
    const arg3 = ptr(0x1400060b8).readPointer();
    console.log(raddr, 'xor3:', arg1, arg2, arg3, arg1.xor(arg2).xor(arg3));
});
Interceptor.attach(ptr(0x1400B8EB9), function step1_cb() {
    console.log('step1', this.context.rcx, this.context.rax);
});
Interceptor.attach(ptr(0x1400B920E), function() {
    console.log("step1 write 1a0a to idx", this.context.rax)
});
 
// Interceptor.attach(ptr(0x1400C8BD8), unknown_cb);
 
let tn = 5;
Interceptor.attach(ptr(0x1400B18F4), function() {
    const rax = ptr(this.context.rax);
    console.log("from:", rax, rax.add(0x20).readU32());
    if(tn > 0) {
        console.log(hexdump(rax, {length:0x40}));
        tn -= 1;
    }
});
 
console.log('reloaded')
0x1400b8e97 and: 0x60 0x3 0x0
step1 0x0 0x0
0x1400b8f2c add: 0x0 0x3 0x3
0x1400b9006 shr: 0x60 0x2 0x18
0x1400b8c41 add: 0x0 0x1 0x1
0x1400b8ce4 sub/cmp: 0x1 0x4 false
0x1400b8e97 and: 0x18 0x3 0x0
step1 0x1 0x0
0x1400b8f2c add: 0x1 0x3 0x4
0x1400b9006 shr: 0x18 0x2 0x6
0x1400b8c41 add: 0x1 0x1 0x2
0x1400b8ce4 sub/cmp: 0x2 0x4 false
0x1400b8e97 and: 0x6 0x3 0x2
step1 0x2 0x2
0x1400b8f2c add: 0x2 0x3 0x5
0x1400b9006 shr: 0x6 0x2 0x1
0x1400b8c41 add: 0x2 0x1 0x3
0x1400b8ce4 sub/cmp: 0x3 0x4 false
0x1400b8e97 and: 0x1 0x3 0x1
step1 0x3 0x1
0x1400b8f2c add: 0x3 0x3 0x6
0x1400b9006 shr: 0x1 0x2 0x0
0x1400b8c41 add: 0x3 0x1 0x4
0x1400b8ce4 sub/cmp: 0x4 0x4 true
0x1400b88fa add: 0x0 0x1 0x1
0x1400b899d sub/cmp: 0x1 0x20 false
0x1400b8ce4 sub/cmp: 0x0 0x4 false
0x1400b8e97 and: 0xc5 0x3 0x1
step1 0x4 0x1
0x1400b8f2c add: 0x4 0x3 0x7
0x1400b9006 shr: 0xc5 0x2 0x31
0x1400b8c41 add: 0x0 0x1 0x1
0x1400b8ce4 sub/cmp: 0x1 0x4 false
0x1400b8e97 and: 0x31 0x3 0x1
step1 0x5 0x1
0x1400b8f2c add: 0x5 0x3 0x8
0x1400b9006 shr: 0x31 0x2 0xc
0x1400b8c41 add: 0x1 0x1 0x2
0x1400b8ce4 sub/cmp: 0x2 0x4 false
0x1400b8e97 and: 0xc 0x3 0x0
step1 0x6 0x0
0x1400b8f2c add: 0x6 0x3 0x9
0x1400b9006 shr: 0xc 0x2 0x3
0x1400b8c41 add: 0x2 0x1 0x3
0x1400b8ce4 sub/cmp: 0x3 0x4 false
0x1400b8e97 and: 0x3 0x3 0x3
step1 0x7 0x3
0x1400b8f2c add: 0x7 0x3 0xa
0x1400b9006 shr: 0x3 0x2 0x0
0x1400b8c41 add: 0x3 0x1 0x4
0x1400b8ce4 sub/cmp: 0x4 0x4 true
0x1400b88fa add: 0x1 0x1 0x2
0x1400b899d sub/cmp: 0x2 0x20 false
0x1400b8ce4 sub/cmp: 0x0 0x4 false
0x1400b8e97 and: 0xef 0x3 0x3
step1 0x8 0x3
0x1400b8f2c add: 0x8 0x3 0xb
0x1400b9006 shr: 0xef 0x2 0x3b
...
0x1400b8e97 and: 0x60 0x3 0x0
step1 0x0 0x0
0x1400b8f2c add: 0x0 0x3 0x3
0x1400b9006 shr: 0x60 0x2 0x18
0x1400b8c41 add: 0x0 0x1 0x1
0x1400b8ce4 sub/cmp: 0x1 0x4 false
0x1400b8e97 and: 0x18 0x3 0x0
step1 0x1 0x0
0x1400b8f2c add: 0x1 0x3 0x4
0x1400b9006 shr: 0x18 0x2 0x6
0x1400b8c41 add: 0x1 0x1 0x2
0x1400b8ce4 sub/cmp: 0x2 0x4 false
0x1400b8e97 and: 0x6 0x3 0x2
step1 0x2 0x2
0x1400b8f2c add: 0x2 0x3 0x5
0x1400b9006 shr: 0x6 0x2 0x1
0x1400b8c41 add: 0x2 0x1 0x3
0x1400b8ce4 sub/cmp: 0x3 0x4 false
0x1400b8e97 and: 0x1 0x3 0x1
step1 0x3 0x1
0x1400b8f2c add: 0x3 0x3 0x6
0x1400b9006 shr: 0x1 0x2 0x0
0x1400b8c41 add: 0x3 0x1 0x4
0x1400b8ce4 sub/cmp: 0x4 0x4 true
0x1400b88fa add: 0x0 0x1 0x1
0x1400b899d sub/cmp: 0x1 0x20 false
0x1400b8ce4 sub/cmp: 0x0 0x4 false
0x1400b8e97 and: 0xc5 0x3 0x1
step1 0x4 0x1
0x1400b8f2c add: 0x4 0x3 0x7
0x1400b9006 shr: 0xc5 0x2 0x31
0x1400b8c41 add: 0x0 0x1 0x1
0x1400b8ce4 sub/cmp: 0x1 0x4 false
0x1400b8e97 and: 0x31 0x3 0x1
step1 0x5 0x1
0x1400b8f2c add: 0x5 0x3 0x8
0x1400b9006 shr: 0x31 0x2 0xc
0x1400b8c41 add: 0x1 0x1 0x2
0x1400b8ce4 sub/cmp: 0x2 0x4 false
0x1400b8e97 and: 0xc 0x3 0x0
step1 0x6 0x0
0x1400b8f2c add: 0x6 0x3 0x9
0x1400b9006 shr: 0xc 0x2 0x3
0x1400b8c41 add: 0x2 0x1 0x3
0x1400b8ce4 sub/cmp: 0x3 0x4 false
0x1400b8e97 and: 0x3 0x3 0x3
step1 0x7 0x3
0x1400b8f2c add: 0x7 0x3 0xa

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回