本帖最后由 006306 于 2020-8-4 07:41 编辑
今天发一篇最基础的教程吧。(不提供原程序与任何补丁文件)
今天的这个插件有点简单了。把一个包含插件的gh文件打开才会弹窗
查壳,无壳和混淆 元数据正常(太没意思了)
弹窗上有active字样。那好办。直接dnspy拖入,搜索active,定位到form窗体的位置
跟进这个click
发现关键函数是this.activator.ActivateLicense(this.productKeyBox.Text);this.activator.ActivateLicense(this.productKeyBox.Text);
进一步跟进这个函数
发现调用了 LexActivator.ActivateLicense();这个函数,并且函数的返回值一定要是0.继续跟进这个函数:
发现了一个关键函数:
int num = (IntPtr.Size == 4) ? LexActivatorNative.ActivateLicense_x86() : LexActivatorNative.ActivateLicense();
上面代码的意思是如果系统是64位的(IntPtr.Size==4)那么调用ActivateLicense_x86(),否则调用ActivateLicense();
根据上下文,这个函数返回值一定要是零
跟进这个函数。发现dllimport关键字样,调用了native代码。
如上图。至此可以分析出dll的调用关系:
1和2是native代码导出的dll。3是对于1和2进行了.net包装
干掉函数
[DllImport("LexActivator32", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "ActivateLicense")]
public static extern int ActivateLicense_x86();
以及[DllImport("LexActivator", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern int ActivateLicense();
即可破解成功。
我们对于LexActivator.dll进行分析。
查壳。无壳。c++2015写的
我们拿IDA看一下
由于dll没有加壳。所以导出函数以及他的地址看的清清楚楚。我们跟进ActivateLicense 000000018002B540 1
这里就是这个函数的的汇编语言代码了。
F5,转为c语言代码
[Asm] 纯文本查看 复制代码 signed __int64 ActivateLicense()
{
__int64 v1; // rbx
__int64 v2; // rax
__int64 v3; // rsi
char v4; // al
__int64 v5; // rdi
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rbx
unsigned __int64 v9; // rdx
char v10; // [rsp+28h] [rbp-D8h]
unsigned __int8 v11; // [rsp+30h] [rbp-D0h]
char v12; // [rsp+38h] [rbp-C8h]
__int64 v13; // [rsp+48h] [rbp-B8h]
__int64 v14; // [rsp+50h] [rbp-B0h]
__int128 v15; // [rsp+58h] [rbp-A8h]
__int64 v16; // [rsp+68h] [rbp-98h]
__int64 v17; // [rsp+70h] [rbp-90h]
char v18; // [rsp+78h] [rbp-88h]
__int64 v19; // [rsp+88h] [rbp-78h]
__int64 v20; // [rsp+90h] [rbp-70h]
char v21; // [rsp+98h] [rbp-68h]
char Dst; // [rsp+100h] [rbp+0h]
v14 = 15i64;
v13 = 0i64;
v12 = 0;
sub_18000D590(&v12);
if ( !(unsigned __int8)sub_18001EEC0(&v12) )
return 43i64;
v14 = 15i64;
v13 = 0i64;
v12 = 0;
sub_18000D6C0(&v12, "ESHFCE", 6ui64);
v17 = 15i64;
v16 = 0i64;
LOBYTE(v15) = 0;
sub_18000D590(&v15);
if ( !(unsigned __int8)sub_180012A90(&v15, &v12, &::Dst) )
return 54i64;
v14 = 15i64;
v13 = 0i64;
v12 = 0;
sub_18000D590(&v12);
if ( !(unsigned __int8)sub_18001EB60(&v12) )
return 54i64;
memset(&Dst, 0, 0x260ui64);
v1 = sub_18001AF50(&Dst);
v2 = sub_18001B6C0((unsigned __int64)&qword_18013A6C8);
sub_18001D400(v2, v1);
sub_18001B270(&Dst);
v16 = 0i64;
v20 = 15i64;
v19 = 0i64;
v18 = 0;
_mm_storeu_si128((__m128i *)&v15, (__m128i)0i64);
sub_18000D590(&v18);
v3 = sub_180003320(&v12, &v15);
sub_18001B800((unsigned __int64)&qword_18013A708);
sub_18001B6C0((unsigned __int64)&qword_18013A6C8);
v4 = sub_180003970(&v21, &Buf2);
v10 = 0;
v5 = (unsigned int)sub_180004DB0((__int64)&v18, v4);
if ( (unsigned __int8)sub_18001EF80(v5) )
{
v6 = sub_18001B6C0((unsigned __int64)&qword_18013A6C8);
v20 = 15i64;
v19 = 0i64;
v18 = 0;
dword_1801380D8 = *(_DWORD *)(v6 + 504);
sub_18000D590(&v18);
v7 = sub_180003970(&v21, &Buf2);
sub_18001BBF0(&v18, v7);
}
v8 = v15;
if ( (_QWORD)v15 )
{
sub_180002270(v15, *((_QWORD *)&v15 + 1), &v15, v11, v3, v10);
v9 = (signed __int64)((unsigned __int128)((v16 - v8) * (signed __int128)7378697629483820647i64) >> 64) >> 4;
sub_180058D30(&v15, v8, v9 + (v9 >> 63));
}
return (unsigned int)v5;
}
函数逻辑写的明明白白。
到这里。我们有3个办法:
对这个dll进行hook.
制作内存补丁。
还有一个就是重新写一个c++ dll.。并且提供相同的dll导出函数。
由于这个dll太小了。所以我选择第三种。
打开visualstudio,新建一个c++ win32项目,命名为LexActivator
根据ida的导出函数以及c语言反汇编代码分析,写出导出函数。
其中 extern "C" __declspec(dllexport) int ActivateLicense() { return 0; }这个函数返回值直接为零就可以。
注意c++与c#的数据对应关系
导出函数全部写好后,选择64位平台,生成dll
拿ida查看一下生成的dll的导出函数:
一个不差
同样。创建一个LexActivator32的c++项目
写好导出函数
选择X86平台,生成dll
用生成的dll替换掉程序本身的dll
破解成功
|