010 Editor 8.0.1 之 逆向分析及注册机编写
一、工具及软件介绍
二、逆向分析
2.1、找到提示错误注册弹窗
2.2、分析跳转处代码
2.3、=2D 函数分析
2.3.1、获取注册码处分析
2.3.2、3处分支分析
2.3.2.1、9C情况
2.3.2.2、FC情况
2.3.2.3、AC情况
2.3.3、用户名处理函数
2.3.3.1、函数调用处分析
2.3.3.2、函数内部分析
2.3.4、用户名处理函数返回值及剩余代码分析
三、注册机编写
3.1、注册机外观
3.2、结果验证
3.2.1、版本授权
3.2.2、天数授权
四、网络验证
4.1、两处判断网络验证是否通过处
4.2、确认是否为网络验证函数
4.3、突破网络验证
五、附件
前言
- 010 Editor 是很好的逆向学习软件,通过编写注册机对提高逆向能力有很大帮助,
- 由于本文写的比较早,发布时已经出9.0版本,特添加9.0版本破解补丁。
一、工具及软件介绍
- 逆向工具:x64 dbg
- 平台:Win_1803 x64 虚拟机
- 破解软件:010 Editor v8.0.1 x64

二、逆向分析
2.1、找到提示错误注册弹窗
接上一篇,通过对CreateWindowExA、CreateWindowExW下断点,并且利用堆栈调用找到关键代码处

找到弹窗中的提示字符串,选中这一行,x64dbg会自动分析出该处是从何处跳转过来的,跟踪并分析
2.2、分析跳转处代码

到达跳转处代码,我们会发现有多组比较跳转,其中一个就是弹出无效的用户名和注册码信息处的跳转。
通过分析推测,这几组比较是判断错误类型的。
此时,我们选中最上方的比较处,会发现该处比较是从哪里跳转过来的,继续跟踪分析。

来到这里我们发现ebx与DB比较,结合分析得出,如果不相等就进入错误判断分支,相等则弹出注册成功弹窗。
我们选中比较处代码,会发现跳转来源,继续跟踪分析。

通过分析该处代码可知,E7来源于第一个CALL中,第二个CALL的返回值是用于判断注册码是否正确的,即返回结果为DB,接着往下看,当esi等于E7,即第一个CALL的返回结果为E7或者rcx + 3c等于0时都会跳转到下边注册码正确判断的流程中去。
此时,我们得出的结论是,当第二个CALL的返回值是DB时,注册就会成功,这里我们将第二个CALL函数打上标签为=DB,方便后续分析。

我们进入=DB这个函数分析一下

我们已经知道,要使注册成功,这个函数就必须返回DB,通个观察这个函数,当7FF715213D46这个函数的返回值为2D时会将这个函数的返回值赋值为DB,同时,我们发现这个函数还会返回E7这个值,这时我们想到在分析=DB这个函数之前也有一个函数可能会返回为E7,我们对比一下这2个函数看看。

我们发现这2个是同一函数,此时根据前后关系分析,当该函数的返回值为E7时会跳转到注册码正确验证处,但这个函数的返回值是E7时,=DB这个函数的返回值却不是DB。
通过这2个条件,我们得出这个函数的返回值在等于2D时,注册会成功。
我们将该函数打上=2D标签,方便分析,同时更改之前的分析注释。

2.3、=2D 函数分析
通过上方分析已知,该函数需要等于2D,才会注册成功。
此时,我们先找到返回值为2D操作的代码。

找到2D赋值处后,我们就需要跟踪调试这个函数了。
通过单步跟踪发现00007FF71704597E之前是获取注册码和一些检测工作
2.3.1、获取注册码处分析
- 使用的测试注册码为:0011-2233-4455-6677-8899

- 注册码与局部变量的对应关系
- KEY[0] = 00 KEY[1] = 11 KEY[2] = 22 KEY[3] = 33 KEY[4] = 44
- KEY[5] = 55 KEY[6] = 66 KEY[7] = 77 KEY[8] = 88 KEY[9] = 99
- 内存中的存储状态【RSP + 28】

- 通过
00007FF71704597E及之后的汇编代码确定数据的存储位置- KEY[0] = [RSP + 28]
- KEY[1] = [RSP + 29]
- KEY[2] = [RSP + 2A]
- KEY[3] = [RSP + 2B]
- KEY[4] = [RSP + 2C]
- KEY[5] = [RSP + 2D]
- KEY[6] = [RSP + 2E]
- KEY[7] = [RSP + 2F]
- KEY[8] = [RSP + 30]
- KEY[9] = [RSP + 31]
00007FF71704597E之后的代码分析


- 通过分析发现,当取出
KEY[3]的值后,有3处比较跳转,分别为9C/FC/AC,对应的C代码如下
switch ( KEY[] )
{
case 0x9C:
break;
case 0xFC:
break;
case 0xAC:
break;
}
- 接下来就可以单独分析每一个分支了
2.3.2、3处分支分析
2.3.2.1、9C情况

- 得到的结果为
- EBX = ((( KEY[0] ^ KEY[6] ) ^ 0x18 ) + 0x3D ) ^ 0xA7
- EAX = (((((( KEY[1] ^ KEY[7] ) * 0x100) + ( KEY[2] ^ KEY[5] )) ^ 0x7892 ) + 0x4d30 ) ^ 0x3421) / 0xB 或 0
- 对应的C代码
case 0x9C:
DWORD EAX = ( ( ( ( ( ( KEY[ ] ^ KEY[ ] ) * 0x100 ) +
( KEY[ ] ^ KEY[ ] ) ) ^ 0x7892 ) + 0x4d30 ) ^ 0x3421 );
DWORD EBX = ( ( ( KEY[ ] ^ KEY[ ] ) ^ 0x18 ) + 0x3D ) ^ 0xA7;
if (EAX % 0xB != )
{
EAX = ; // error
}
if (EAX == || EAX > 0x3E8)
{
return; // error
}
if (EBX == )
{
return; // error
}
// 如果EBX >= 0x2 EBX = 0 否则不变
// EBX 做为下面用户名处理函数的参数
if ( EBX >= 0x2 )
{
EBX = ;
}
// EAX 做为下面用户名处理函数的参数
EAX = EAX / 0xB;
break;
2.3.2.2、FC情况

- 得到的结果为
- EBX = FF
- EAX = 0x1
- 由于后面的判断,如果是
0xFC,是不会返回0x2D的,这里略
2.3.2.3、AC情况

- 得到的结果为
- EBX = EAX
- DWORD PTR DS:[RDI+0x30] = (((((( KEY[1] ^ KEY[7] ) * 0x100) + ( KEY[2] ^ KEY[5] )) ^ 0x7892 ) + 0x4d30 ) ^ 0x3421) / 0xB 或 0
- 对应的C代码
case 0xAC:
DWORD EAX = ( ( ( ( ( ( KEY[ ] ^ KEY[ ] ) * 0x100 ) +
( KEY[ ] ^ KEY[ ] ) ) ^ 0x7892 ) + 0x4d30 ) ^ 0x3421 );
if ( EAX % 0xB != )
{
EAX = ; // error
}
if ( EAX == || EAX > 0x3E8 )
{
return; // error
}
DWORD ECX = ( ( ( ( ( ( ( KEY[ ] ^ KEY[ ] ) << 0x8 ) + ( ( KEY[ ] ^ KEY[ ] ) << 0x10 ) + ( KEY[ ] ^ KEY[ ] ) ) ^ 0x5B8C27 ) ^ 0x22C078 ) - 0x2C175 ) ^ 0xFFE53167 ) & 0xFFFFFF; EAX = 0xF0F0F0F1;
DWORD EDX = ;
// 伪代码:EDX : EAX = EAX * ECX
EDX = EDX >> 0x4;
EAX = EDX * 0x11;
ECX = ECX - EAX;
if (ECX == ) // ECX = EAX
{
EAX = EDX; // Right
}
else
{
EAX = ;
}
DWORD RDI0x30 = EAX / 0xB;
EBX = EAX;
break;
2.3.3、用户名处理函数
2.3.3.1、函数调用处分析

- 上面已经准备好了
EBX和RDI + 30的值 - 结合IDA分析得出,用户名处理函数的参数如下:
- 参数一:用户名字符串首地址
- 参数二:如果类型是
0xFC就是0,否则是1,用于函数内部判断类型 - 参数三:准备好的
EBX - 参数四:准备好的
RDI + 30
2.3.3.2、函数内部分析


void function( char* name )
{
DWORD KEY[ ] = { 0x9C };
DWORD EBX = ;
DWORD RDI30 = ;
DWORD LOCAL1 = ;
DWORD LOCAL2 = ( EBX/*参数3*/ * 0x11 ) & 0xFF;
DWORD LOCAL3 = ;
DWORD LOCAL4 = ;
DWORD ESI = RDI30/*参数4*/ * 0xF;
int NameLen = strlen( name );
char EAX[ ] = { }; // 函数返回值
DWORD PW[ ] = {
0x39CB44B8, 0x23754F67, 0x5F017211, 0x3EBB24DA, 0x351707C6, 0x63F9774B, 0x17827288, 0x0FE74821,
…………
0x5CFF0261, 0x33AE061E, 0x3BB6345F, 0x5D814A75, 0x257B5DF4, 0x0A5C2C5B, 0x16A45527, 0x16F23945 };
for ( int i = ; i < NameLen; i++ )
{
char nameChar = toupper( name[ i ] );
if ( KEY[ ] != 0xFC )
{
LOCAL1 = ( PW[ nameChar ] ^ PW[ nameChar + 0xD ] ) * PW[ nameChar + 0x2F ]
+ PW[ LOCAL2 ]
+ PW[ ESI ]
+ PW[ LOCAL3 ];
}
else
{
LOCAL1 = ( PW[ nameChar ] ^ PW[ nameChar + 0x3F ] ) + PW[ nameChar + 0x17 ]
+ PW[ LOCAL2 ]
+ PW[ ESI ]
+ PW[ LOCAL4 ];
}
LOCAL3 += 0x13;
LOCAL2 += 0x9;
ESI += 0xD;
LOCAL4 += 0x7;
}
*( DWORD* ) EAX = LOCAL1;
}
2.3.4、用户名处理函数返回值及剩余代码分析

- 通过分析发现,当
KEY[3] = 0xFC时,不会跳转到正确的返回值赋值处 - 所以,,当
KEY[3] = 0xFC时,之后的代码都不用分析 - 对应C代码如下
void function1()
{
DWORD KEY[ ] = { };
DWORD EAX[ ] = { };
if ( KEY[ ] == EAX[ ] &&
KEY[ ] == EAX[ ] &&
KEY[ ] == EAX[ ] &&
KEY[ ] == EAX[ ] )
{
switch ( KEY[] )
{
case 0x9C:
/*
正确
*/
break;
case 0xFC:
/*
错误
*/
break;
case 0xAC:
/*
正确
*/
break;
}
}
}
三、注册机编写
- 本次使用MFC编写注册机
- 全局数组密码表(内存中提取)
DWORD PW[ ] = {
0x39CB44B8, 0x23754F67, 0x5F017211, 0x3EBB24DA, 0x351707C6, 0x63F9774B, 0x17827288, 0x0FE74821,
0x5B5F670F, 0x48315AE8, 0x785B7769, 0x2B7A1547, 0x38D11292, 0x42A11B32, 0x35332244, 0x77437B60,
0x1EAB3B10, 0x53810000, 0x1D0212AE, 0x6F0377A8, 0x43C03092, 0x2D3C0A8E, 0x62950CBF, 0x30F06FFA,
0x34F710E0, 0x28F417FB, 0x350D2F95, 0x5A361D5A, 0x15CC060B, 0x0AFD13CC, 0x28603BCF, 0x3371066B,
0x30CD14E4, 0x175D3A67, 0x6DD66A13, 0x2D3409F9, 0x581E7B82, 0x76526B99, 0x5C8D5188, 0x2C857971,
0x15F51FC0, 0x68CC0D11, 0x49F55E5C, 0x275E4364, 0x2D1E0DBC, 0x4CEE7CE3, 0x32555840, 0x112E2E08,
0x6978065A, 0x72921406, 0x314578E7, 0x175621B7, 0x40771DBF, 0x3FC238D6, 0x4A31128A, 0x2DAD036E,
0x41A069D6, 0x25400192, 0x00DD4667, 0x6AFC1F4F, 0x571040CE, 0x62FE66DF, 0x41DB4B3E, 0x3582231F,
0x55F6079A, 0x1CA70644, 0x1B1643D2, 0x3F7228C9, 0x5F141070, 0x3E1474AB, 0x444B256E, 0x537050D9,
0x0F42094B, 0x2FD820E6, 0x778B2E5E, 0x71176D02, 0x7FEA7A69, 0x5BB54628, 0x19BA6C71, 0x39763A99,
0x178D54CD, 0x01246E88, 0x3313537E, 0x2B8E2D17, 0x2A3D10BE, 0x59D10582, 0x37A163DB, 0x30D6489A,
0x6A215C46, 0x0E1C7A76, 0x1FC760E7, 0x79B80C65, 0x27F459B4, 0x799A7326, 0x50BA1782, 0x2A116D5C,
0x63866E1B, 0x3F920E3C, 0x55023490, 0x55B56089, 0x2C391FD1, 0x2F8035C2, 0x64FD2B7A, 0x4CE8759A,
0x518504F0, 0x799501A8, 0x3F5B2CAD, 0x38E60160, 0x637641D8, 0x33352A42, 0x51A22C19, 0x085C5851,
0x032917AB, 0x2B770AC7, 0x30AC77B3, 0x2BEC1907, 0x035202D0, 0x0FA933D3, 0x61255DF3, 0x22AD06BF,
0x58B86971, 0x5FCA0DE5, 0x700D6456, 0x56A973DB, 0x5AB759FD, 0x330E0BE2, 0x5B3C0DDD, 0x495D3C60,
0x53BD59A6, 0x4C5E6D91, 0x49D9318D, 0x103D5079, 0x61CE42E3, 0x7ED5121D, 0x14E160ED, 0x212D4EF2,
0x270133F0, 0x62435A96, 0x1FA75E8B, 0x6F092FBE, 0x4A000D49, 0x57AE1C70, 0x004E2477, 0x561E7E72,
0x468C0033, 0x5DCC2402, 0x78507AC6, 0x58AF24C7, 0x0DF62D34, 0x358A4708, 0x3CFB1E11, 0x2B71451C,
0x77A75295, 0x56890721, 0x0FEF75F3, 0x120F24F1, 0x01990AE7, 0x339C4452, 0x27A15B8E, 0x0BA7276D,
0x60DC1B7B, 0x4F4B7F82, 0x67DB7007, 0x4F4A57D9, 0x621252E8, 0x20532CFC, 0x6A390306, 0x18800423,
0x19F3778A, 0x462316F0, 0x56AE0937, 0x43C2675C, 0x65CA45FD, 0x0D604FF2, 0x0BFD22CB, 0x3AFE643B,
0x3BF67FA6, 0x44623579, 0x184031F8, 0x32174F97, 0x4C6A092A, 0x5FB50261, 0x01650174, 0x33634AF1,
0x712D18F4, 0x6E997169, 0x5DAB7AFE, 0x7C2B2EE8, 0x6EDB75B4, 0x5F836FB6, 0x3C2A6DD6, 0x292D05C2,
0x052244DB, 0x149A5F4F, 0x5D486540, 0x331D15EA, 0x4F456920, 0x483A699F, 0x3B450F05, 0x3B207C6C,
0x749D70FE, 0x417461F6, 0x62B031F1, 0x2750577B, 0x29131533, 0x588C3808, 0x1AEF3456, 0x0F3C00EC,
0x7DA74742, 0x4B797A6C, 0x5EBB3287, 0x786558B8, 0x00ED4FF2, 0x6269691E, 0x24A2255F, 0x62C11F7E,
0x2F8A7DCD, 0x643B17FE, 0x778318B8, 0x253B60FE, 0x34BB63A3, 0x5B03214F, 0x5F1571F4, 0x1A316E9F,
0x7ACF2704, 0x28896838, 0x18614677, 0x1BF569EB, 0x0BA85EC9, 0x6ACA6B46, 0x1E43422A, 0x514D5F0E,
0x413E018C, 0x307626E9, 0x01ED1DFA, 0x49F46F5A, 0x461B642B, 0x7D7007F2, 0x13652657, 0x6B160BC5,
0x65E04849, 0x1F526E1C, 0x5A0251B6, 0x2BD73F69, 0x2DBF7ACD, 0x51E63E80, 0x5CF2670F, 0x21CD0A03,
0x5CFF0261, 0x33AE061E, 0x3BB6345F, 0x5D814A75, 0x257B5DF4, 0x0A5C2C5B, 0x16A45527, 0x16F23945
};
- 获取随机数小于
0x3E8的函数(获取注册人数)
DWORD GetRandNum() {
DWORD Result;
srand( ( unsigned ) time( NULL ) );
return Result = rand() % 0x3E8; // 用于获取随机区间,(0, 3E8],为注册人数 1 ~ 1000
}
- 用户名处理函数
- 参数1:用户名
- 参数2:注册人数(随机函数获取)
- 参数3:注册天数(当版本注册【0x9C】时 = 0,当时间注册时【0xAC】时=要注册的年月日 - 1970.1.1之间的天数)
void CKeyGenDlg::GetEncryStr( char * szName, DWORD Regmen, DWORD day )
{
DWORD ESI = Regmen * 0xF;
DWORD LOCAL1 = ;
DWORD LOCAL2 = ( day * 0x11 ) & 0xFF;
DWORD LOCAL3 = ;
//DWORD LOCAL4 = 0;
BYTE EAX[ ] = { };
int NameLen = strlen( szName );
for ( int i = ; i < NameLen; i++ )
{
char nameChar = toupper( szName[ i ] );
LOCAL1 =
( ( ( LOCAL1 + PW[ nameChar ] ) ^ PW[ ( nameChar + 0xD ) & 0xFF ] )*PW[ ( nameChar + 0x2F ) & 0xFF ] )
+ PW[ LOCAL2 ]
+ PW[ ESI & 0xFF ]
+ PW[ LOCAL3 ]; ESI += 0xD;
LOCAL2 += 0x9;
LOCAL3 += 0x13;
}
*( DWORD* ) EAX = LOCAL1;
KEY[ ] = EAX[ ];
KEY[ ] = EAX[ ];
KEY[ ] = EAX[ ];
KEY[ ] = EAX[ ];
}
- 注册码计算函数
- 参数1:用户名
- 参数2:注册天数
- 通过该函数可以根据用户名计算出注册码,同时可计算版本注册及天数注册(按选择不同区分)
void CKeyGenDlg::CalcReg( char * szName, DWORD day )
{
char destbuff[ ] = { };
DWORD Regmen = GetRandNum();
/*
判断是否整除函数的结果为:Regmen
对应公式为:Regmen = ((((( KEY[1] ^ KEY[7] ) * 0x100 + ( KEY[2] ^ KEY[5] )) ^ 0x7892 ) + 0x4D30 ) ^ 0x3421) / 0xB
逆向计算得出:( KEY[1] ^ KEY[7] ) * 0x100 + ( KEY[2] ^ KEY[5] ) 的值,WORD
*/
WORD tmp = ( ( ( Regmen * 0xB ) ^ 0x3421 ) - 0x4D30 ) ^ 0x7892; USES_CONVERSION;
if ( status )
{
//MessageBox( L"版本", 0, 0 );
KEY[ ] = 0x9C;
day = ; // 当为版本注册时,天数必须为0
GetEncryStr( szName, Regmen, day );
KEY[ ] = ( HIBYTE( tmp ) ) ^ KEY[ ];
KEY[ ] = ( LOBYTE( tmp ) ) ^ KEY[ ];
/*
版本号 9 < ((( KEY[0] ^ KEY[6] ) ^ 0x18 ) + 0x3D ) ^ 0xA7
这里取 0x18
*/
KEY[ ] = ( ( ( 0x18 ^ 0xA7 ) - 0x3D ) ^ 0x18 ) ^ KEY[ ];
sprintf_s( destbuff, "%02X%02X-%02X%02X-%02X%02X-%02X%02X", KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ] );
m_Reg = A2T( destbuff );
UpdateData( FALSE );
}
else
{
//MessageBox( L"天数", 0, 0 );
KEY[ ] = 0xAC;
GetEncryStr( szName, Regmen, day );
KEY[ ] = ( HIBYTE( tmp ) ) ^ KEY[ ];
KEY[ ] = ( LOBYTE( tmp ) ) ^ KEY[ ];
// 通过天数逆向推导得出计算之前的数值
/*
day = ((((((( KEY[9] ^ KEY[5] ) << 0x10 ) + (( KEY[4] ^ KEY[8] ) << 0x8 ) + KEY[0] ^ KEY[6])xor 005B8C27)
xor 0x22c078) - 0x2C175) xor 0xFFE53167) and 0xFFFFFF
*/
DWORD tmp2 = ( ( ( ( day * 0x11 ) ^ 0xFFE53167 ) + 0x2C175 ) ^ 0x22C078 ) ^ 0x5B8C27;
KEY[ ] = ( tmp2 & 0xFF ) ^ KEY[ ];
KEY[ ] = ( ( tmp2 >> 0x8 ) & 0xFF ) ^ KEY[ ];
KEY[ ] = ( ( tmp2 >> 0x10 ) & 0xFF ) ^ KEY[ ];
sprintf_s( destbuff, "%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ], KEY[ ] );
m_Reg = A2T( destbuff );
UpdateData( FALSE );
}
}
- 按钮响应函数
- 该函数对运算逻辑及数据进行处理,当用户名不为空时,计算注册码
void CKeyGenDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
// CDialogEx::OnOK();
memset( KEY, , sizeof( KEY ) ); // 清空数组
UpdateData( TRUE );
if ( !m_User.IsEmpty() )
{
USES_CONVERSION;
char * szName = T2A( m_User );
DWORD day = 0x7224; // 1970.1.1 - 指定日期的天数
CalcReg( szName, day );
}
else
{
MessageBox( _T( "用户名不能为空" ), , MB_ICONWARNING );
}
}
3.1、注册机外观
由于使用了单选控件,于是在选择授权方式时对注册码编辑框进行处理

3.2、结果验证
3.2.1、版本授权


3.2.2、天数授权


四、网络验证
4.1、两处判断网络验证是否通过处
- 第一处

- 第二处

总结:当RCX + 3C处的值为0时,走正常流程,否则,使用注册机注册的将会提示注册码无效。

继续观察第一处,在网络验证处下方有一个函数,我们进去浏览会发现网址拼接,网址拼接中会发现有name和pwd字样,此时怀疑该函数可能就是修改RCX + 3C处的值的函数。
4.2、确认是否为网络验证函数
- 可以通过新建虚拟机或修改
RCX + 3C处的值为0,通过修改ZF标志位强制执行该函数,验证结果如下

4.3、突破网络验证
- 方法一:将两处网络验证比较处的跳转进行修改,即
JE→JMP,使其强制执行网络验证通过后的代码 - 方法二:进入网络验证函数在其函数头直接
RET将函数返回,不对RCX + 3C进行修改
总结:突破网络验证的方法有很多,还需要多学习。
五、附件
010 Editor 8.0.1 提取码:d6ds
010 Editor 9.0 提取码:0lfe
六、源码
说明:移植MFC部分代码,使用Qt重写,并为时间注册添加自选时间功能
GitHub:KenGen
010 Editor 8.0.1 之 逆向分析及注册机编写的更多相关文章
- 010 Editor v8.0.1(32 - bit) 算法逆向分析、注册机编写
010 Editor 的逆向分析整体算下来还是比较简单的,将程序拖入OD,通过字符串搜索定位到核心代码,经过分析,主要是如下图所示的两个关键函数,返回正确的值,才算是注册成功. 00409C9B 这个 ...
- 010 Editor 8.0.1 之 暴力破解
一.工具及软件介绍二.破解1.打开调试程序2.打开注册页面3.在弹出窗口API中下断4.点击注册按钮5.逐一进去观察6.找到正确的授权字符串7.找到函数头8.找到计算出EBX的CALL9.进入函数跟踪 ...
- [转]Wing IDE 6.0 安装及算号器注册机代码
下载安装wing 选择第三个,运行算号器,输入license id 输入request id. Python 2 算号器注册机代码 import string import random import ...
- Navicat Premium 15.0.17 破解激活(DFoX 注册机)
Navicat Premium v15.0.17 安装程序和注册机已放入百度网盘,下载地址在本文最后 1. 下载并安装 Navicat Premium 15 在官网下载 Windows 版本的 Nav ...
- 深入底层逆向分析TDC‘s keygenme(手脱压缩壳)
系统 : Windows xp 程序 : TDC‘s keygenme 程序下载地址 :http://pan.baidu.com/s/1gdWyt6z 要求 : 脱壳 & 注册机编写 使用工具 ...
- [应用软件] VMware Workstation 12.0.0 Pro 正式版下载【附注册机+注册码】
软件信息 软件名称: VMware Workstation 软件版本: 12 软件大小: 300 MB 软件语言: 简体中文 更新时间: - 软件授权: 免费 软件类别: 安装版 运行环境: WinX ...
- IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习
相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...
- C++反汇编与逆向分析技术揭秘
C++反汇编-继承和多重继承 学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...
- Android逆向分析(2) APK的打包与安装背后的故事
前言 上一次我们反编译了手Q,并遇到了Apktool反编译直接crash的问题,虽然笔者很想在这次解决这个问题,但在解决途中,发现该保护依赖于很多知识,所以本次先插入一下,正所谓知其然知其所以然,授之 ...
随机推荐
- group by 拓展
Oracle的group by除了基本使用方法以外,还有3种扩展使用方法,各自是rollup.cube.grouping sets.分别介绍例如以下: 1.rollup 对数据库表emp.如果当中两个 ...
- 小程序坑之 swiper组件
表现:swiper 内容 空白 原因:swiper组件的current值为n时,重新刷新页面,current值不变,当刷新后的swiper item的数量少于 n 时,swpier找不到对应的item ...
- react基础学习 一
1. 搭建环境 安装react脚手架 >npm install create-react-app -g 创建文件 >create-react-app 项目名称 启动 ...
- react基础学习 二——生命周期
生命周期mount: mounting装载创建 update更新 unmounting卸载 错误捕获 注意点:生命周期函数的 作用,什么之后用 只有类式组件有生命周期,函数式组件没有生命周期 moun ...
- 如何解决fiddler的响应显示乱码问题
fiddler中Response出现乱码, 这是因为HTML被压缩了, 我们可以通过两种方法去解压.方法1:点击Response Raw上方的"Response is encoded any ...
- 74.纯 CSS 创作一台 MacBook Pro
原文地址:https://segmentfault.com/a/1190000015568609 HTML code: <div class="macbook"> &l ...
- wdk1703+vs2015编译的诡异问题
最近将wdk升级到1703(10.0.15063.0)版本,编译一个新建的minifiter项目居然出现了失败 提示错误为 WindowsDriver.common.targets(460,5): e ...
- 201772020113 李清华《面向对象程序设计(java)》第17周学习总结
1.实验目的与要求 (1) 掌握线程同步的概念及实现技术: (2) 线程综合编程练习 2.实验内容和步骤 实验1:测试程序并进行代码注释. 测试程序1: l 在Elipse环境下调试教材651页程序 ...
- 201772020113 李清华《面向对象程序设计(java)》第16周学习总结
1.实验目的与要求 (1) 掌握线程概念: (2) 掌握线程创建的两种技术: (3) 理解和掌握线程的优先级属性及调度方法: (4) 掌握线程同步的概念及实现技术: 2.实验内容和步骤 实验1:测试程 ...
- Windows服务器
知道了怎么装VMware workstation并且创建虚拟机装上了系统配好网络