【文章标题】Ultra Video Joiner注册分析 附 注册机(上)
【联系作者】zhong_sf@sina.com
【软件名称】Ultra Video Joiner
【附件下载】
http://www.onlinedown.net/soft/55635.htm文章太长了,提交不上去,只能分成两部分发表了!!!
这是一款与视频相关的软件,用于视频格式转换与视频合成等,未注册版本只能完成所有工作的50%,注册方式是传统的用户名+序列号的方式 ,加了壳,不清楚什么壳,也不会脱,都是带壳调试分析的。注册的代码量挺大的,整个过程下来感觉挺痛苦的。
软件的注册过程中使用了一种新的数据结构,与这个结构相关的类有两个,为了方便,暂且将其命名为Small与 Large, 定义分别如下:
class Small
{
public:
protected:
public:
unsigned int nValids; //这个是整数的最高有效位个数,4个字节为一 位
unsigned int* Pdata; //Pdata是用于存放整数的空间
unsigned int nMaxSpace; //这个字节记录Pdata的最大空间,单位为4个字节
unsigned int nReferCount; //引用计数,因为该对象的空间可能被共享,尤其是在两个对象赋值时!
};
class Large
{
Public:
Protected:
Private:
Small* Psmasll; //Small对象指针
unsigned int SignFlags; //记录Small对象正负的符号标记,因为Small是无符号的,大整数. 0为正,1为负
};
该结构表示一个大整数,可以无限大,且对这个结构定义了许多运算,但为了简单,在写注册机的时候我将这两个类压缩成一个类LargeInt,定义如下:
class LargeInt
{
public:
//Constructor
LargeInt();
~LargeInt();
LargeInt(unsigned int nInitNum);
LargeInt(const LargeInt& lgCopy);
LargeInt& operator= (const LargeInt& lgCopy);
//Get and set
void _OutPutlgInt();
unsigned int _GetSignFlags();
unsigned int _GetValids();
unsigned int _GetMaxLoc();
unsigned int _GetData(unsigned int nIndex);
unsigned int _GetDataBit(unsigned int nIndex);
void _Zero();
void _SetSignFlags(unsigned int nSign);
void _SetData(unsigned int nIndex ,unsigned int nData);
void _UnSignedCopy(LargeInt* PlgOptor);
void _Datacpy(unsigned int* PuInt ,unsigned int nNum);
//Compare operation
int _UnSignedCmp(LargeInt* lgInt);
int _SignedCmp(LargeInt* lgInt);
//Number Operation
unsigned int _CalcLastData();
void _UnsignedAdd(LargeInt* PlgOp1 ,LargeInt* PlgOp2);
void _UnsignedSub(LargeInt* PlgOp1 ,LargeInt* PlgOp2);
void _UnSignedMulVariant(LargeInt* PlgOp1 ,LargeInt* PlgOp2 ,unsigned int nInitLast);
void _SignedAdd(LargeInt* PlgOp1 ,LargeInt* PlgOp2);
void _SignedSub(LargeInt* PlgOp1 ,LargeInt* PlgOp2);
void _SignedMulVariant(LargeInt* PlgOp1 ,LargeInt* PlgOp2);
//UnNamed Proc
void _UnNamed24D0();
void _UnNamed2510();
LargeInt _UnNamed2E10(LargeInt* PlgParam1 ,LargeInt* PlgParam2);
void _UnNamed2F80(LargeInt* PlgParam1 ,LargeInt* PlgParam2);
void _UnName2550(unsigned int nParam);
void _UnName3490(LargeInt* PlgParam1 ,LargeInt* PlgParam2,
LargeInt* Plgq8 ,LargeInt* Plgq24 ,LargeInt* p3 ,unsigned int nq20);
void _UnName3660(LargeInt* plg1 ,LargeInt* plg2 ,LargeInt* plg3);
void _CalcSerialInt(LargeInt* Plg10 ,LargeInt* PlgConst30 ,LargeInt* PlgConst38 ,LargeInt* PlgConst40);
private:
unsigned int nSignFlag;
unsigned int nValids;
unsigned int* Pdata;
unsigned int nMaxLoc;
};
原本的两个类中定义了很多的成员函数,调试的时候可以发现,每当F7跟进一个函数时,看到的又是一大片函数,很是痛苦,只能猜一部分跟一部分,上面这些是我提取出来的一些比较有用的,很多是多个函数内联整合而来的。因为没接触过什么加密算法,跟了很多次都看不出作者使用的是什么经典的算法,看来以后这方面得加强!
好吧,开始分析吧,能过MessageBoxA下断再经过几层的回溯很容易找到注册的入口点,这里不就再详述了,整个注册过程是在AppSys模块的_Check函数中进行的,下面是_Check过程:
1.0_Check:
002E1640 >/$ 64:A1 00000000 mov eax,dword ptr fs:[0]
002E1646 |. 6A FF push -0x1
002E1648 |. 68 7AAA2E00 push AppSys.002EAA7A
002E164D |. 50 push eax
002E164E |. 64:8925 00000000 mov dword ptr fs:[0],esp
002E1655 |. 81EC 84030000 sub esp,0x384
002E165B |. B9 40000000 mov ecx,0x40
002E1660 |. 33C0 xor eax,eax
002E1662 |. 53 push ebx
002E1663 |. 55 push ebp
002E1664 |. 56 push esi
002E1665 |. 57 push edi
002E1666 |. 8DBC24 90020000 lea edi,dword ptr ss:[esp+0x290]
002E166D |. 8D9424 90020000 lea edx,dword ptr ss:[esp+0x290]
002E1674 |. F3:AB rep stos dword ptr es:[edi]
002E1676 |. AA stos byte ptr es:[edi] ; memset(lpBuf290 ,0 ,0x100)
002E1677 |. B9 40000000 mov ecx,0x40
002E167C |. 33C0 xor eax,eax
002E167E |. 8DBC24 88000000 lea edi,dword ptr ss:[esp+0x88]
002E1685 |. F3:AB rep stos dword ptr es:[edi]
002E1687 |. AA stos byte ptr es:[edi] ; memset(lpBuf88 ,0 ,0x100)
002E1688 |. B9 40000000 mov ecx,0x40
002E168D |. 33C0 xor eax,eax
002E168F |. 8DBC24 8C010000 lea edi,dword ptr ss:[esp+0x18C]
002E1696 |. F3:AB rep stos dword ptr es:[edi]
002E1698 |. AA stos byte ptr es:[edi] ; memset(lpBuf18c ,0 ,0x100)
002E1699 |. 8B3D F0FE2E00 mov edi,dword ptr ds:[0x2EFEF0] ; -------------------
002E169F |. 83C9 FF or ecx,0xFFFFFFFF
002E16A2 |. 33C0 xor eax,eax
002E16A4 |. F2:AE repne scas byte ptr es:[edi]
002E16A6 |. F7D1 not ecx
002E16A8 |. 2BF9 sub edi,ecx
002E16AA |. 8BC1 mov eax,ecx
002E16AC |. 8BF7 mov esi,edi ; strcpy(lpBuf290 ,szSfName)
002E16AE |. 8BFA mov edi,edx
002E16B0 |. 8D9424 88000000 lea edx,dword ptr ss:[esp+0x88]
002E16B7 |. C1E9 02 shr ecx,0x2
002E16BA |. F3:A5 rep movs dword ptr es:[edi],dword>
002E16BC |. 8BC8 mov ecx,eax
002E16BE |. 33C0 xor eax,eax
002E16C0 |. 83E1 03 and ecx,0x3
002E16C3 |. F3:A4 rep movs byte ptr es:[edi],byte p>; ---------------------
002E16C5 |. 8BBC24 A4030000 mov edi,dword ptr ss:[esp+0x3A4] ; ---------------------
002E16CC |. 83C9 FF or ecx,0xFFFFFFFF
002E16CF |. F2:AE repne scas byte ptr es:[edi]
002E16D1 |. F7D1 not ecx
002E16D3 |. 2BF9 sub edi,ecx
002E16D5 |. 8BC1 mov eax,ecx
002E16D7 |. 8BF7 mov esi,edi ; strcpy(lpBuf88 ,szUserName)
002E16D9 |. 8BFA mov edi,edx
002E16DB |. C1E9 02 shr ecx,0x2
002E16DE |. F3:A5 rep movs dword ptr es:[edi],dword>
002E16E0 |. 8BC8 mov ecx,eax
002E16E2 |. 83E1 03 and ecx,0x3
002E16E5 |. F3:A4 rep movs byte ptr es:[edi],byte p>; ---------------------
002E16E7 |. 33C9 xor ecx,ecx
002E16E9 |> 8A840C 88000000 /mov al,byte ptr ss:[esp+ecx+0x88>; -----------------
002E16F0 |. 3C 20 |cmp al,0x20
002E16F2 |. 74 23 |je XAppSys.002E1717
002E16F4 |. 84C0 |test al,al
002E16F6 |. 74 1F |je XAppSys.002E1717
002E16F8 |. 3C 30 |cmp al,0x30
002E16FA |. 7C 04 |jl XAppSys.002E1700
002E16FC |. 3C 39 |cmp al,0x39 ; 若lpBuf88[ecx]不是:
002E16FE |. 7E 17 |jle XAppSys.002E1717 ; 1.数字字符 2.大小写字母 3.空格 4.0
002E1700 |> 3C 61 |cmp al,0x61
002E1702 |. 7C 04 |jl XAppSys.002E1708 ; 则:
002E1704 |. 3C 7A |cmp al,0x7A ; lpBuf88[ecx] = ecx
002E1706 |. 7E 0F |jle XAppSys.002E1717
002E1708 |> 3C 41 |cmp al,0x41
002E170A |. 7C 04 |jl XAppSys.002E1710
002E170C |. 3C 5A |cmp al,0x5A
002E170E |. 7E 07 |jle XAppSys.002E1717
002E1710 |> 888C0C 88000000 |mov byte ptr ss:[esp+ecx+0x88],c>
002E1717 |> 41 |inc ecx
002E1718 |. 81F9 00010000 |cmp ecx,0x100
002E171E |.^ 7C C9 \jl XAppSys.002E16E9 ; --------------------
002E1720 |. 33C0 xor eax,eax ; --------------------
002E1722 |> 8A8C04 88000000 /mov cl,byte ptr ss:[esp+eax+0x88>
002E1729 |. 8A9C04 90020000 |mov bl,byte ptr ss:[esp+eax+0x29>
002E1730 |. 02CB |add cl,bl ; lpBuf18c[eax] = lpBuf88[eax] + lpBuf290[eax]
002E1732 |. 888C04 8C010000 |mov byte ptr ss:[esp+eax+0x18C],>
002E1739 |. 40 |inc eax
002E173A |. 3D 00010000 |cmp eax,0x100
002E173F |.^ 7C E1 \jl XAppSys.002E1722 ; ---------------------
002E1741 |. 6A 00 push 0x0 ; ---------------------
002E1743 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
002E1747 |. E8 D4120000 call AppSys.002E2A20
002E174C |. 6A 00 push 0x0
002E174E |. 8D4C24 24 lea ecx,dword ptr ss:[esp+0x24]
002E1752 |. C78424 A0030000 0000>mov dword ptr ss:[esp+0x3A0],0x0
002E175D |. E8 BE120000 call AppSys.002E2A20
002E1762 |. 6A 00 push 0x0
002E1764 |. 8D4C24 2C lea ecx,dword ptr ss:[esp+0x2C] ; 编号为 2A20 的函数为 对象Large 的构造函数
002E1768 |. C68424 A0030000 01 mov byte ptr ss:[esp+0x3A0],0x1 ; 一系列对象的构造函数
002E1770 |. E8 AB120000 call AppSys.002E2A20
002E1775 |. 6A 00 push 0x0
002E1777 |. 8D4C24 34 lea ecx,dword ptr ss:[esp+0x34]
002E177B |. C68424 A0030000 02 mov byte ptr ss:[esp+0x3A0],0x2
002E1783 |. E8 98120000 call AppSys.002E2A20
002E1788 |. 6A 00 push 0x0
002E178A |. 8D4C24 3C lea ecx,dword ptr ss:[esp+0x3C]
002E178E |. C68424 A0030000 03 mov byte ptr ss:[esp+0x3A0],0x3
002E1796 |. E8 85120000 call AppSys.002E2A20
002E179B |. 6A 00 push 0x0
002E179D |. 8D4C24 44 lea ecx,dword ptr ss:[esp+0x44]
002E17A1 |. C68424 A0030000 04 mov byte ptr ss:[esp+0x3A0],0x4
002E17A9 |. E8 72120000 call AppSys.002E2A20 ; ---------------------
002E17AE |. B3 05 mov bl,0x5
002E17B0 |. 6A 04 push 0x4
002E17B2 |. 68 40D02E00 push AppSys.002ED040
002E17B7 |. 8D4C24 40 lea ecx,dword ptr ss:[esp+0x40]
002E17BB |. 889C24 A4030000 mov byte ptr ss:[esp+0x3A4],bl
002E17C2 |. E8 29110000 call AppSys.002E28F0 ; <=> memcpy(lgInt38->pdata ,0x2CD040 ,4*4)
002E17C7 |. 6A 04 push 0x4 ; 地址0x2CD040不固定,但上面的数据都是一样的常数,后面亦是如此
002E17C9 |. 68 50D02E00 push AppSys.002ED050
002E17CE |. 8D4C24 48 lea ecx,dword ptr ss:[esp+0x48]
002E17D2 |. E8 19110000 call AppSys.002E28F0 ; <=> memcpy(lgInt4040.pdata ,0x2CD050 ,4*4)
002E17D7 |. 8B15 60D02E00 mov edx,dword ptr ds:[0x2ED060]
002E17DD |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E17E1 |. 52 push edx
002E17E2 |. E8 39120000 call AppSys.002E2A20
002E17E7 |. 8D4424 18 lea eax,dword ptr ss:[esp+0x18]
002E17EB |. 8D4C24 30 lea ecx,dword ptr ss:[esp+0x30]
002E17EF |. 50 push eax
002E17F0 |. C68424 A0030000 06 mov byte ptr ss:[esp+0x3A0],0x6
002E17F8 |. E8 83120000 call AppSys.002E2A80 ; lgnt30 = lgInt18 赋值构造函数
002E17FD |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18] ; lgInt18上的数据为常数0x10001,在构造函数中放入的
002E1801 |. 889C24 9C030000 mov byte ptr ss:[esp+0x39C],bl
002E1808 |. E8 C3120000 call AppSys.002E2AD0
002E180D |. 6A 08 push 0x8
002E180F |. 68 64D02E00 push AppSys.002ED064
002E1814 |. 8D4C24 30 lea ecx,dword ptr ss:[esp+0x30]
002E1818 |. E8 D3100000 call AppSys.002E28F0 ; memcpy(lgInt28.pdata ,0x2CD064 ,8*4) 其实这份数据在后面没用上
002E181D |. B9 08000000 mov ecx,0x8 ; ------------------
002E1822 |. 33C0 xor eax,eax
002E1824 |. 8D7C24 68 lea edi,dword ptr ss:[esp+0x68]
002E1828 |. 33D2 xor edx,edx
002E182A |. F3:AB rep stos dword ptr es:[edi] ; <=> memset (lpBuf68 ,0 ,0x8*4)
002E182C |. 8DBC24 8C010000 lea edi,dword ptr ss:[esp+0x18C]
002E1833 |. 83C9 FF or ecx,0xFFFFFFFF
002E1836 |. F2:AE repne scas byte ptr es:[edi]
002E1838 |. F7D1 not ecx
002E183A |. 49 dec ecx
002E183B |. 74 21 je XAppSys.002E185E
002E183D |> 8A8C14 8C010000 /mov cl,byte ptr ss:[esp+edx+0x18>
002E1844 |. 8DBC24 8C010000 |lea edi,dword ptr ss:[esp+0x18C] ; <=> strcpy(lpBuf68 ,lpBuf18c)
002E184B |. 884C14 68 |mov byte ptr ss:[esp+edx+0x68],c>
002E184F |. 83C9 FF |or ecx,0xFFFFFFFF
002E1852 |. 33C0 |xor eax,eax
002E1854 |. 42 |inc edx
002E1855 |. F2:AE |repne scas byte ptr es:[edi]
002E1857 |. F7D1 |not ecx
002E1859 |. 49 |dec ecx
002E185A |. 3BD1 |cmp edx,ecx
002E185C |.^ 72 DF \jb XAppSys.002E183D ; -----------------
002E185E |> B9 08000000 mov ecx,0x8 ; -----------------
002E1863 |. 33C0 xor eax,eax
002E1865 |. 8D7C24 48 lea edi,dword ptr ss:[esp+0x48]
002E1869 |. F3:AB rep stos dword ptr es:[edi] ; <=> memset(lpBuf48 ,0 ,0x8*4)
002E186B |> 33D2 /xor edx,edx
002E186D |. 33C9 |xor ecx,ecx
002E186F |. 8A5404 68 |mov dl,byte ptr ss:[esp+eax+0x68>
002E1873 |. 8A4C04 69 |mov cl,byte ptr ss:[esp+eax+0x69>
002E1877 |. C1E2 08 |shl edx,0x8
002E187A |. 03D1 |add edx,ecx ; 将 lpBuf68 中每个dword 的每个字节 逆序
002E187C |. 33C9 |xor ecx,ecx ; 转存于 lpBuf48 中
002E187E |. 8A4C04 6A |mov cl,byte ptr ss:[esp+eax+0x6A>
002E1882 |. 83C0 04 |add eax,0x4
002E1885 |. C1E2 08 |shl edx,0x8
002E1888 |. 03D1 |add edx,ecx
002E188A |. 33C9 |xor ecx,ecx
002E188C |. 8A4C04 67 |mov cl,byte ptr ss:[esp+eax+0x67>
002E1890 |. C1E2 08 |shl edx,0x8
002E1893 |. 03D1 |add edx,ecx
002E1895 |. 83F8 20 |cmp eax,0x20
002E1898 |. 895404 44 |mov dword ptr ss:[esp+eax+0x44],>
002E189C |.^ 7C CD \jl XAppSys.002E186B ; ------------------
002E189E |. 8D5424 48 lea edx,dword ptr ss:[esp+0x48]
002E18A2 |. 6A 08 push 0x8
002E18A4 |. 52 push edx
002E18A5 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E18A9 |. E8 42100000 call AppSys.002E28F0 ; memcpy(lgInt10.pdata ,lpbuf48 ,8*4)
002E18AE |. 8D4424 10 lea eax,dword ptr ss:[esp+0x10]
002E18B2 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E18B6 |. 50 push eax
002E18B7 |. 51 push ecx
002E18B8 |. 8D4C24 30 lea ecx,dword ptr ss:[esp+0x30]
002E18BC |. E8 EF030000 call AppSys.002E1CB0 ; lgInt18 = lgInt28._CalcSerialInt ( lgInt10 )
002E18C1 |. 50 push eax
002E18C2 |. 8D4C24 24 lea ecx,dword ptr ss:[esp+0x24]
002E18C6 |. C68424 A0030000 07 mov byte ptr ss:[esp+0x3A0],0x7
002E18CE |. E8 AD110000 call AppSys.002E2A80 ; lgInt20 = lgInt18
002E18D3 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E18D7 |. 889C24 9C030000 mov byte ptr ss:[esp+0x39C],bl
002E18DE |. E8 ED110000 call AppSys.002E2AD0
002E18E3 |. 8D5424 48 lea edx,dword ptr ss:[esp+0x48]
002E18E7 |. 6A 08 push 0x8
002E18E9 |. 52 push edx
002E18EA |. 8D4C24 28 lea ecx,dword ptr ss:[esp+0x28]
002E18EE |. E8 3D100000 call AppSys.002E2930 ; 将lgInt20 中的前8个整数 拷贝到 lpBuf48中
002E18F3 |. 8B4424 58 mov eax,dword ptr ss:[esp+0x58]
002E18F7 |. 8B4C24 54 mov ecx,dword ptr ss:[esp+0x54]
002E18FB |. 8B5424 50 mov edx,dword ptr ss:[esp+0x50]
002E18FF |. 8B7424 4C mov esi,dword ptr ss:[esp+0x4C]
002E1903 |. 8B7C24 64 mov edi,dword ptr ss:[esp+0x64]
002E1907 |. 8B6C24 5C mov ebp,dword ptr ss:[esp+0x5C]
002E190B |. 8D1C08 lea ebx,dword ptr ds:[eax+ecx]
002E190E |. 03DA add ebx,edx
002E1910 |. 03DE add ebx,esi
002E1912 |. 33FB xor edi,ebx ; edi = lpBuf48[7]xor(lpBuf48[4]+lpBuf48[3]+lpBuf48[2]+lpBuf48[1])
002E1914 |. 8B5C24 48 mov ebx,dword ptr ss:[esp+0x48]
002E1918 |. 03EB add ebp,ebx
002E191A |. 8B5C24 60 mov ebx,dword ptr ss:[esp+0x60]
002E191E |. 33DD xor ebx,ebp ; ebx = (lpBuf48[6] xor (lpBuf48[5]+lpBuf48[0]))
002E1920 |. 8B6C24 5C mov ebp,dword ptr ss:[esp+0x5C]
002E1924 |. 895C24 60 mov dword ptr ss:[esp+0x60],ebx
002E1928 |. 03DD add ebx,ebp
002E192A |. 8B6C24 48 mov ebp,dword ptr ss:[esp+0x48]
002E192E |. 897C24 64 mov dword ptr ss:[esp+0x64],edi
002E1932 |. 03DD add ebx,ebp
002E1934 |. 03DF add ebx,edi
002E1936 |. 03D8 add ebx,eax
002E1938 |. 8D8424 88000000 lea eax,dword ptr ss:[esp+0x88]
002E193F |. 03D9 add ebx,ecx
002E1941 |. 03DA add ebx,edx ; ebx = (lpBuf48[6]xor(lpBuf48[5]+lpBuf48[0]))+edi +
002E1943 |. 03DE add ebx,esi ; lpBuf48[5]+lpBuf48[0]+lpBuf48[4]+lpBuf48[3]+lpBuf48[2]+lpBuf48[1]
002E1945 |. 53 push ebx
002E1946 |. 68 04D12E00 push AppSys.002ED104 ; ASCII "%08lX"
002E194B |. 50 push eax
002E194C |. E8 F7200000 call AppSys.002E3A48 ; wsprintf (szSerial ,"%08lx" ,ebx)
002E1951 |. 8B9424 B4030000 mov edx,dword ptr ss:[esp+0x3B4]
002E1958 |. 8D8C24 94000000 lea ecx,dword ptr ss:[esp+0x94]
002E195F |. 6A 08 push 0x8
002E1961 |. 51 push ecx
002E1962 |. 52 push edx
002E1963 |. E8 A8200000 call AppSys.002E3A10 ; <=> strCmp(szPassword ,szSerial)
002E1968 |. 83C4 18 add esp,0x18 ; 将输入的假码与szSerial比较,仅比较前8字节
002E196B |. 85C0 test eax,eax
002E196D |. 5F pop edi
002E196E |. 5E pop esi
002E196F |. 5D pop ebp
002E1970 |. 5B pop ebx
002E1971 |. 0F85 83000000 jnz AppSys.002E19FA ; ------------------
002E1977 |. 8D4C24 30 lea ecx,dword ptr ss:[esp+0x30]
002E197B |. C68424 8C030000 09 mov byte ptr ss:[esp+0x38C],0x9
002E1983 |. E8 48110000 call AppSys.002E2AD0
002E1988 |. 8D4C24 28 lea ecx,dword ptr ss:[esp+0x28]
002E198C |. C68424 8C030000 08 mov byte ptr ss:[esp+0x38C],0x8
002E1994 |. E8 37110000 call AppSys.002E2AD0
002E1999 |. 8D4C24 20 lea ecx,dword ptr ss:[esp+0x20]
002E199D |. C68424 8C030000 0A mov byte ptr ss:[esp+0x38C],0xA
002E19A5 |. E8 26110000 call AppSys.002E2AD0
002E19AA |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E19AE |. C68424 8C030000 01 mov byte ptr ss:[esp+0x38C],0x1
002E19B6 |. E8 15110000 call AppSys.002E2AD0
002E19BB |. 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
002E19BF |. C68424 8C030000 00 mov byte ptr ss:[esp+0x38C],0x0
002E19C7 |. E8 04110000 call AppSys.002E2AD0
002E19CC |. 8D4C24 00 lea ecx,dword ptr ss:[esp]
002E19D0 |. C78424 8C030000 FFFF>mov dword ptr ss:[esp+0x38C],-0x1 ; 编号为 2AD0的函数 为 Large类的析构函数
002E19DB |. E8 F0100000 call AppSys.002E2AD0
002E19E0 |. B8 01000000 mov eax,0x1
002E19E5 |. 8B8C24 84030000 mov ecx,dword ptr ss:[esp+0x384]
002E19EC |. 64:890D 00000000 mov dword ptr fs:[0],ecx
002E19F3 |. 81C4 90030000 add esp,0x390
002E19F9 |. C3 retn
002E19FA |> 8D4C24 30 lea ecx,dword ptr ss:[esp+0x30]
002E19FE |. C68424 8C030000 0C mov byte ptr ss:[esp+0x38C],0xC
002E1A06 |. E8 C5100000 call AppSys.002E2AD0
002E1A0B |. 8D4C24 28 lea ecx,dword ptr ss:[esp+0x28]
002E1A0F |. C68424 8C030000 0B mov byte ptr ss:[esp+0x38C],0xB
002E1A17 |. E8 B4100000 call AppSys.002E2AD0
002E1A1C |. 8D4C24 20 lea ecx,dword ptr ss:[esp+0x20]
002E1A20 |. C68424 8C030000 0D mov byte ptr ss:[esp+0x38C],0xD
002E1A28 |. E8 A3100000 call AppSys.002E2AD0
002E1A2D |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E1A31 |. C68424 8C030000 01 mov byte ptr ss:[esp+0x38C],0x1
002E1A39 |. E8 92100000 call AppSys.002E2AD0
002E1A3E |. 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
002E1A42 |. C68424 8C030000 00 mov byte ptr ss:[esp+0x38C],0x0
002E1A4A |. E8 81100000 call AppSys.002E2AD0
002E1A4F |. 8D4C24 00 lea ecx,dword ptr ss:[esp]
002E1A53 |. C78424 8C030000 FFFF>mov dword ptr ss:[esp+0x38C],-0x1
002E1A5E |. E8 6D100000 call AppSys.002E2AD0 ; ------------------
002E1A63 |. 8B8C24 84030000 mov ecx,dword ptr ss:[esp+0x384]
002E1A6A |. 33C0 xor eax,eax
002E1A6C |. 64:890D 00000000 mov dword ptr fs:[0],ecx
002E1A73 |. 81C4 90030000 add esp,0x390
002E1A79 \. C3 retn
整个过程应该是很了然的,在上面的过程中主要是构造了3个对象,lgInt30 , lgInt38 , lgInt40 ,lgInt10 ,lgInt28. 其中除lgInt10外, 其它的对象中放入的都是常数。lgInt10中放入的都是用户输入用户名经过一定的运算之后得到的一系列4字节整数(8个整数),这几个数据将会在后面的计算 _CalcSerialInt()中用,很明显,接下来我们得F7跟进 _CalcSerialInt.
注:因为这是软件C++写的,因此一般多个参数的函数,其第一个参数都是本身并非函数参数,而是函数外待用函数返回值赋值的对象的地址,这种情况是在函数返回对象时出现的。如 object a = _Func(b ,c) => push c ,push b ,push addr a ,call _Func. 这点在这个软件中经常出现。
1.1. 下面是 _CalcSerialInt(),的代码,这个过程是最核心的,也很长,得多点耐心. 这个过程主要是使用上层函数 _Check 中构造的3个对象进行运算,只有lgInt10是通过参数传入的的,其它都是在在函数中通过 lgInt10地址的的偏移来引用的:
002E1CAF 90 nop ; lgParam1 = lgInt28._CalcSerialInt ( lgParam )
002E1CB0 /$ 6A FF push -0x1
002E1CB2 |. 68 B7AB2E00 push AppSys.002EABB7 ; SE 处理程序安装
002E1CB7 |. 64:A1 00000000 mov eax,dword ptr fs:[0]
002E1CBD |. 50 push eax
002E1CBE |. 64:8925 00000000 mov dword ptr fs:[0],esp
002E1CC5 |. 81EC AC000000 sub esp,0xAC
002E1CCB |. 53 push ebx
002E1CCC |. 55 push ebp
002E1CCD |. 56 push esi
002E1CCE |. 8BE9 mov ebp,ecx
002E1CD0 |. 57 push edi
002E1CD1 |. 6A 01 push 0x1
002E1CD3 |. 8D4C24 58 lea ecx,dword ptr ss:[esp+0x58]
002E1CD7 |. C74424 24 00000000 mov dword ptr ss:[esp+0x24],0x0
002E1CDF |. E8 3C0D0000 call AppSys.002E2A20
002E1CE4 |. 6A 01 push 0x1
002E1CE6 |. 8D4C24 60 lea ecx,dword ptr ss:[esp+0x60]
002E1CEA |. C78424 C8000000 0100>mov dword ptr ss:[esp+0xC8],0x1
002E1CF5 |. E8 260D0000 call AppSys.002E2A20
002E1CFA |. 8D4424 54 lea eax,dword ptr ss:[esp+0x54]
002E1CFE |. 8D75 18 lea esi,[arg.5] ; esi = plgInt40
002E1D01 |. 50 push eax
002E1D02 |. 8D4C24 68 lea ecx,dword ptr ss:[esp+0x68]
002E1D06 |. 56 push esi
002E1D07 |. 51 push ecx
002E1D08 |. C68424 D0000000 02 mov byte ptr ss:[esp+0xD0],0x2
002E1D10 |. E8 DB0F0000 call AppSys.002E2CF0 ; lgInt64L = lgInt40 - 1
002E1D15 |. 8BD8 mov ebx,eax
002E1D17 |. 8D5424 68 lea edx,dword ptr ss:[esp+0x68]
002E1D1B |. 8D7D 10 lea edi,[arg.3] ; edi = plgInt38
002E1D1E |. 52 push edx
002E1D1F |. 8D8424 BC000000 lea eax,dword ptr ss:[esp+0xBC]
002E1D26 |. 57 push edi
002E1D27 |. 50 push eax
002E1D28 |. C68424 DC000000 03 mov byte ptr ss:[esp+0xDC],0x3
002E1D30 |. E8 BB0F0000 call AppSys.002E2CF0 ; lgIntACL = lgInt38 - 1
002E1D35 |. 53 push ebx
002E1D36 |. 8D8C24 98000000 lea ecx,dword ptr ss:[esp+0x98]
002E1D3D |. 50 push eax
002E1D3E |. 51 push ecx
002E1D3F |. C68424 E8000000 04 mov byte ptr ss:[esp+0xE8],0x4
002E1D47 |. E8 24100000 call AppSys.002E2D70 ; lgInt7CL = (lgInt38 - 1) X (lgInt40 - 1)
002E1D4C |. 83C5 08 add ebp,0x8
002E1D4F |. 50 push eax
002E1D50 |. 8D5424 4C lea edx,dword ptr ss:[esp+0x4C]
002E1D54 |. 55 push ebp
002E1D55 |. 52 push edx
002E1D56 |. C68424 F4000000 05 mov byte ptr ss:[esp+0xF4],0x5
002E1D5E |. E8 1D120000 call AppSys.002E2F80 ; lgInt24L = _Func2F80 (lgInt30 ,lgInt7CL)
002E1D63 |. 83C4 30 add esp,0x30
002E1D66 |. 8D4C24 7C lea ecx,dword ptr ss:[esp+0x7C]
002E1D6A |. C68424 C4000000 0B mov byte ptr ss:[esp+0xC4],0xB
002E1D72 |. E8 590D0000 call AppSys.002E2AD0
002E1D77 |. 8D8C24 AC000000 lea ecx,dword ptr ss:[esp+0xAC]
002E1D7E |. C68424 C4000000 0A mov byte ptr ss:[esp+0xC4],0xA
002E1D86 |. E8 450D0000 call AppSys.002E2AD0
002E1D8B |. 8D4C24 64 lea ecx,dword ptr ss:[esp+0x64]
002E1D8F |. C68424 C4000000 09 mov byte ptr ss:[esp+0xC4],0x9
002E1D97 |. E8 340D0000 call AppSys.002E2AD0
002E1D9C |. 8D4C24 5C lea ecx,dword ptr ss:[esp+0x5C]
002E1DA0 |. C68424 C4000000 08 mov byte ptr ss:[esp+0xC4],0x8
002E1DA8 |. E8 230D0000 call AppSys.002E2AD0
002E1DAD |. 8D4C24 54 lea ecx,dword ptr ss:[esp+0x54]
002E1DB1 |. C68424 C4000000 07 mov byte ptr ss:[esp+0xC4],0x7
002E1DB9 |. E8 120D0000 call AppSys.002E2AD0
002E1DBE |. 56 push esi
002E1DBF |. 8D4424 30 lea eax,dword ptr ss:[esp+0x30]
002E1DC3 |. 57 push edi
002E1DC4 |. 50 push eax
002E1DC5 |. E8 B6110000 call AppSys.002E2F80 ; lgInt2CL = _Func2F80 ( lgInt38 , lgInt40 )
002E1DCA |. 83C4 0C add esp,0xC
002E1DCD |. 6A 01 push 0x1
002E1DCF |. 8D4C24 48 lea ecx,dword ptr ss:[esp+0x48]
002E1DD3 |. C68424 C8000000 0C mov byte ptr ss:[esp+0xC8],0xC
002E1DDB |. E8 400C0000 call AppSys.002E2A20
002E1DE0 |. 8D4C24 44 lea ecx,dword ptr ss:[esp+0x44]
002E1DE4 |. 8D9424 9C000000 lea edx,dword ptr ss:[esp+0x9C]
002E1DEB |. 51 push ecx
002E1DEC |. 57 push edi
002E1DED |. 52 push edx
002E1DEE |. C68424 D0000000 0D mov byte ptr ss:[esp+0xD0],0xD
002E1DF6 |. E8 F50E0000 call AppSys.002E2CF0 ; lgInt9CL = lgInt38 - 1
002E1DFB |. 50 push eax
002E1DFC |. 8D4424 34 lea eax,dword ptr ss:[esp+0x34]
002E1E00 |. 8D4C24 5C lea ecx,dword ptr ss:[esp+0x5C]
002E1E04 |. 50 push eax
002E1E05 |. 51 push ecx
002E1E06 |. C68424 DC000000 0E mov byte ptr ss:[esp+0xDC],0xE
002E1E0E |. E8 BD100000 call AppSys.002E2ED0 ; lgInt4CL = _Func2ED0(lgInt24L ,(lgInt38 - 1))
002E1E13 |. 83C4 18 add esp,0x18
002E1E16 |. 8D8C24 9C000000 lea ecx,dword ptr ss:[esp+0x9C]
002E1E1D |. C68424 C4000000 11 mov byte ptr ss:[esp+0xC4],0x11
002E1E25 |. E8 A60C0000 call AppSys.002E2AD0
002E1E2A |. 8D4C24 44 lea ecx,dword ptr ss:[esp+0x44]
002E1E2E |. C68424 C4000000 10 mov byte ptr ss:[esp+0xC4],0x10
002E1E36 |. E8 950C0000 call AppSys.002E2AD0
002E1E3B |. 6A 01 push 0x1
002E1E3D |. 8D4C24 38 lea ecx,dword ptr ss:[esp+0x38]
002E1E41 |. E8 DA0B0000 call AppSys.002E2A20
002E1E46 |. 8D5424 34 lea edx,dword ptr ss:[esp+0x34]
002E1E4A |. 8D8424 8C000000 lea eax,dword ptr ss:[esp+0x8C]
002E1E51 |. 52 push edx
002E1E52 |. 56 push esi
002E1E53 |. 50 push eax
002E1E54 |. C68424 D0000000 12 mov byte ptr ss:[esp+0xD0],0x12
002E1E5C |. E8 8F0E0000 call AppSys.002E2CF0 ; lgInt8CL = lgInt40 - 1
002E1E61 |. 8D4C24 30 lea ecx,dword ptr ss:[esp+0x30]
002E1E65 |. 50 push eax
002E1E66 |. 8D5424 4C lea edx,dword ptr ss:[esp+0x4C]
002E1E6A |. 51 push ecx
002E1E6B |. 52 push edx
002E1E6C |. C68424 DC000000 13 mov byte ptr ss:[esp+0xDC],0x13
002E1E74 |. E8 57100000 call AppSys.002E2ED0 ; lgInt3CL = _Func2EDO (lgInt24L ,(lgInt40 - 1))
002E1E79 |. 83C4 18 add esp,0x18
002E1E7C |. 8D8C24 8C000000 lea ecx,dword ptr ss:[esp+0x8C]
002E1E83 |. C68424 C4000000 16 mov byte ptr ss:[esp+0xC4],0x16
002E1E8B |. E8 400C0000 call AppSys.002E2AD0
002E1E90 |. 8D4C24 34 lea ecx,dword ptr ss:[esp+0x34]
002E1E94 |. C68424 C4000000 15 mov byte ptr ss:[esp+0xC4],0x15
002E1E9C |. E8 2F0C0000 call AppSys.002E2AD0
002E1EA1 |. 8BAC24 D0000000 mov ebp,dword ptr ss:[esp+0xD0] ; ebp = lgParam
002E1EA8 |. 57 push edi
002E1EA9 |. 8D4424 70 lea eax,dword ptr ss:[esp+0x70]
002E1EAD |. 55 push ebp
002E1EAE |. 50 push eax
002E1EAF |. E8 1C100000 call AppSys.002E2ED0 ; lgInt6CL = _Func2ED0 ( lgParam , lgInt38 )
002E1EB4 |. 8D4C24 58 lea ecx,dword ptr ss:[esp+0x58]
002E1EB8 |. 57 push edi
002E1EB9 |. 51 push ecx
002E1EBA |. 8D5424 2C lea edx,dword ptr ss:[esp+0x2C]
002E1EBE |. 50 push eax
002E1EBF |. 52 push edx
002E1EC0 |. C68424 E0000000 17 mov byte ptr ss:[esp+0xE0],0x17
002E1EC8 |. E8 93170000 call AppSys.002E3660 ; lgInt18L =_Func3660 (lgInt6CL ,lgInt4CL ,lgInt38)
002E1ECD |. 83C4 1C add esp,0x1C
002E1ED0 |. 8D4C24 6C lea ecx,dword ptr ss:[esp+0x6C]
002E1ED4 |. C68424 C4000000 19 mov byte ptr ss:[esp+0xC4],0x19
002E1EDC |. E8 EF0B0000 call AppSys.002E2AD0
002E1EE1 |. 56 push esi
002E1EE2 |. 8D4424 78 lea eax,dword ptr ss:[esp+0x78]
002E1EE6 |. 55 push ebp
002E1EE7 |. 50 push eax
002E1EE8 |. E8 E30F0000 call AppSys.002E2ED0 ; lgInt74L = _2EDO(plgParam ,lgInt40)
002E1EED |. 8D4C24 48 lea ecx,dword ptr ss:[esp+0x48]
002E1EF1 |. 56 push esi
002E1EF2 |. 51 push ecx
002E1EF3 |. 8D5424 24 lea edx,dword ptr ss:[esp+0x24]
002E1EF7 |. 50 push eax
002E1EF8 |. 52 push edx
002E1EF9 |. C68424 E0000000 1A mov byte ptr ss:[esp+0xE0],0x1A
002E1F01 |. E8 5A170000 call AppSys.002E3660 ; lgInt10L = _Func3660 ( lgInt74L ,lgInt3CL ,lgInt40 )
002E1F06 |. 83C4 1C add esp,0x1C
002E1F09 |. 8D4C24 74 lea ecx,dword ptr ss:[esp+0x74]
002E1F0D |. C68424 C4000000 1C mov byte ptr ss:[esp+0xC4],0x1C
002E1F15 |. E8 B60B0000 call AppSys.002E2AD0
002E1F1A |. 8D4424 18 lea eax,dword ptr ss:[esp+0x18]
002E1F1E |. 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
002E1F22 |. 50 push eax
002E1F23 |. 51 push ecx
002E1F24 |. E8 A7090000 call AppSys.002E28D0
002E1F29 |. 83C4 08 add esp,0x8
002E1F2C |. 85C0 test eax,eax
002E1F2E |. 74 0A je XAppSys.002E1F3A ; if (lgInt10L < lgInt18L)
002E1F30 |. 56 push esi ; {
002E1F31 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
002E1F35 |. E8 C60B0000 call AppSys.002E2B00 ; lgInt10L = lgInt10L + lgInt40
002E1F3A |> 8D5424 18 lea edx,dword ptr ss:[esp+0x18] ; }
002E1F3E |. 8D4424 10 lea eax,dword ptr ss:[esp+0x10]
002E1F42 |. 52 push edx
002E1F43 |. 8D8C24 B8000000 lea ecx,dword ptr ss:[esp+0xB8]
002E1F4A |. 50 push eax
002E1F4B |. 51 push ecx
002E1F4C |. E8 9F0D0000 call AppSys.002E2CF0 ; lgIntB4L = lgInt10L - lgInt18L
002E1F51 |. 8D5424 38 lea edx,dword ptr ss:[esp+0x38]
002E1F55 |. C68424 D0000000 1D mov byte ptr ss:[esp+0xD0],0x1D
002E1F5D |. 52 push edx
002E1F5E |. 50 push eax
002E1F5F |. 8D8424 B8000000 lea eax,dword ptr ss:[esp+0xB8]
002E1F66 |. 50 push eax
002E1F67 |. E8 040E0000 call AppSys.002E2D70 ; lgIntA4L = lgIntB4L X lgInt2CL
002E1F6C |. 56 push esi
002E1F6D |. 8D8C24 B0000000 lea ecx,dword ptr ss:[esp+0xB0]
002E1F74 |. 50 push eax
002E1F75 |. 51 push ecx
002E1F76 |. C68424 E8000000 1E mov byte ptr ss:[esp+0xE8],0x1E
002E1F7E |. E8 4D0F0000 call AppSys.002E2ED0 ; lgInt98L = _Func2EDO (lgIntA4L ,lgInt40)
002E1F83 |. 50 push eax
002E1F84 |. 8D9424 AC000000 lea edx,dword ptr ss:[esp+0xAC]
002E1F8B |. B3 1F mov bl,0x1F
002E1F8D |. 57 push edi
002E1F8E |. 52 push edx
002E1F8F |. 889C24 F4000000 mov byte ptr ss:[esp+0xF4],bl
002E1F96 |. E8 D50D0000 call AppSys.002E2D70 ; lgInt84L = lgInt38 X lgInt98L
002E1F9B |. 8BB424 FC000000 mov esi,dword ptr ss:[esp+0xFC]
002E1FA2 |. 50 push eax
002E1FA3 |. 8D4424 4C lea eax,dword ptr ss:[esp+0x4C]
002E1FA7 |. C68424 F8000000 20 mov byte ptr ss:[esp+0xF8],0x20
002E1FAF |. 50 push eax
002E1FB0 |. 56 push esi
002E1FB1 |. E8 BA0C0000 call AppSys.002E2C70 ; lgParam1 = _Func2C70 ( lgInt18L ,lgInt84L )
002E1FB6 |. 83C4 3C add esp,0x3C
002E1FB9 |. C74424 20 01000000 mov dword ptr ss:[esp+0x20],0x1 ; ---------
002E1FC1 |. 8D8C24 84000000 lea ecx,dword ptr ss:[esp+0x84]
002E1FC8 |. 889C24 C4000000 mov byte ptr ss:[esp+0xC4],bl
002E1FCF |. E8 FC0A0000 call AppSys.002E2AD0
002E1FD4 |. 8D8C24 94000000 lea ecx,dword ptr ss:[esp+0x94]
002E1FDB |. C68424 C4000000 1E mov byte ptr ss:[esp+0xC4],0x1E
002E1FE3 |. E8 E80A0000 call AppSys.002E2AD0
002E1FE8 |. 8D8C24 A4000000 lea ecx,dword ptr ss:[esp+0xA4]
002E1FEF |. C68424 C4000000 1D mov byte ptr ss:[esp+0xC4],0x1D
002E1FF7 |. E8 D40A0000 call AppSys.002E2AD0
002E1FFC |. 8D8C24 B4000000 lea ecx,dword ptr ss:[esp+0xB4]
002E2003 |. C68424 C4000000 1C mov byte ptr ss:[esp+0xC4],0x1C
002E200B |. E8 C00A0000 call AppSys.002E2AD0
002E2010 |. 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10] ; 局部对象的析构
002E2014 |. C68424 C4000000 19 mov byte ptr ss:[esp+0xC4],0x19
002E201C |. E8 AF0A0000 call AppSys.002E2AD0
002E2021 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
002E2025 |. C68424 C4000000 15 mov byte ptr ss:[esp+0xC4],0x15
002E202D |. E8 9E0A0000 call AppSys.002E2AD0
002E2032 |. 8D4C24 3C lea ecx,dword ptr ss:[esp+0x3C]
002E2036 |. C68424 C4000000 10 mov byte ptr ss:[esp+0xC4],0x10
002E203E |. E8 8D0A0000 call AppSys.002E2AD0
002E2043 |. 8D4C24 4C lea ecx,dword ptr ss:[esp+0x4C]
002E2047 |. C68424 C4000000 0C mov byte ptr ss:[esp+0xC4],0xC
002E204F |. E8 7C0A0000 call AppSys.002E2AD0
002E2054 |. 8D4C24 2C lea ecx,dword ptr ss:[esp+0x2C]
002E2058 |. C68424 C4000000 07 mov byte ptr ss:[esp+0xC4],0x7
002E2060 |. E8 6B0A0000 call AppSys.002E2AD0
002E2065 |. 8D4C24 24 lea ecx,dword ptr ss:[esp+0x24]
002E2069 |. C68424 C4000000 00 mov byte ptr ss:[esp+0xC4],0x0
002E2071 |. E8 5A0A0000 call AppSys.002E2AD0 ; ----------
002E2076 |. 8B8C24 BC000000 mov ecx,dword ptr ss:[esp+0xBC]
002E207D |. 8BC6 mov eax,esi
002E207F |. 5F pop edi
002E2080 |. 5E pop esi
002E2081 |. 5D pop ebp
002E2082 |. 5B pop ebx
002E2083 |. 64:890D 00000000 mov dword ptr fs:[0],ecx
002E208A |. 81C4 B8000000 add esp,0xB8
002E2090 \. C2 0800 retn 0x8
这里涉及到比较多的函数函数,+ ,- ,x以及一些未知功能的运算。
首先来看编号为2CF0的函数,这个是带符号位的减运算。
1.1.1.带符号的运算是是通过Large类方法来控制的,Small对象的运算都是无符号的,
比如减运算 op1 – op2, 如果op1 < op2 , 则Large 方法则调用 Small的方法: Sub(op2 ,op1),减后再将符号位置为1。下面F7跟进2CF0,前面几层是Large类对运算的控制,再调用Small类对象的该运算(较大数 - 较小数),都比较简单,我们直接跟到Small类的该运算:
002E262F 90 nop ; Small._UnSignedSub(Param)
002E2630 /$ 51 push ecx
002E2631 |. 55 push ebp
002E2632 |. 8BE9 mov ebp,ecx
002E2634 |. 56 push esi
002E2635 |. 57 push edi
002E2636 |. 8B45 00 mov eax,dword ptr ss:[ebp]
002E2639 |. 33F6 xor esi,esi
002E263B |. 33FF xor edi,edi
002E263D |. 894424 0C mov dword ptr ss:[esp+0xC],eax
002E2641 |. 85C0 test eax,eax
002E2643 |. 76 38 jbe XAppSys.002E267D
002E2645 |. 53 push ebx
002E2646 |> 8B4C24 18 /mov ecx,dword ptr ss:[esp+0x18] ; while (edi < nValids)
002E264A |. 57 |push edi ; {
002E264B |. E8 50FAFFFF |call AppSys.002E20A0
002E2650 |. 8BD8 |mov ebx,eax
002E2652 |. 03DE |add ebx,esi ; ebx = Param._GetData(edi) + cf
002E2654 |. 3BDE |cmp ebx,esi
002E2656 |. 72 1B |jb XAppSys.002E2673 ; if (上步相加未溢出)
002E2658 |. 57 |push edi ; {
002E2659 |. 8BCD |mov ecx,ebp
002E265B |. E8 40FAFFFF |call AppSys.002E20A0
002E2660 |. 8BC8 |mov ecx,eax
002E2662 |. 2BCB |sub ecx,ebx ; ecx = _GetData(edi) - ebx
002E2664 |. 3BC1 |cmp eax,ecx
002E2666 |. 51 |push ecx
002E2667 |. 1BF6 |sbb esi,esi
002E2669 |. 57 |push edi
002E266A |. 8BCD |mov ecx,ebp
002E266C |. F7DE |neg esi ; esi = 上步相减运算的 cf值
002E266E |. E8 EDFAFFFF |call AppSys.002E2160 ; _SetData(edi ,ecx)
002E2673 |> 8B4424 10 |mov eax,dword ptr ss:[esp+0x10] ; }
002E2677 |. 47 |inc edi
002E2678 |. 3BF8 |cmp edi,eax
002E267A |.^ 72 CA \jb XAppSys.002E2646 ; }
002E267C |. 5B pop ebx
002E267D |> 5F pop edi
002E267E |. 5E pop esi
002E267F |. 5D pop ebp
002E2680 |. 59 pop ecx
002E2681 \. C2 0400 retn 0x4
整个带符号运算对应的C++语言代码如下,其中该函数内还有些函数就不分析了,看下面的C++代码吧:
void LargeInt::_SignedSub(
LargeInt* PlgOp1,
LargeInt* PlgOp2
)
{
if (PlgOp1->_GetSignFlags() == PlgOp2->_GetSignFlags())
{
if (PlgOp1->_UnSignedCmp(PlgOp2) > 0)
{
_UnsignedSub(PlgOp1 ,PlgOp2);
nSignFlag = PlgOp1->_GetSignFlags();
}
else
if (PlgOp1->_UnSignedCmp(PlgOp2) < 0)
{
_UnsignedSub(PlgOp2 ,PlgOp1);
nSignFlag = (PlgOp1->_GetSignFlags() == 0)? 1 : 0;
}
else
_Zero();
}
else
{
_UnsignedAdd(PlgOp1 ,PlgOp2);
nSignFlag = PlgOp1->_GetSignFlags();
}
}
int LargeInt::_UnSignedCmp(
LargeInt* lgInt
)
{
if (_GetValids() > lgInt->_GetValids())
return 1;
else
if (_GetValids() < lgInt->_GetValids())
return -1;
else
{
for (int i = _GetValids() ;i > 0 ;i--)
{
if (_GetData(i-1) > lgInt->_GetData(i-1))
return 1;
else
if (_GetData(i-1) < lgInt->_GetData(i-1))
return -1;
}
return 0;
}
}
void LargeInt::_UnsignedSub(
LargeInt* PlgOp1,
LargeInt* PlgOp2
)
{
unsigned int nNumLoc = PlgOp1->_GetValids();
unsigned int nCflag = 0 ,nOptorf ,nOptors ,nTmp;
_Zero();
for (unsigned int i = 0 ;i <= nNumLoc ;i++)
{
nOptorf = PlgOp2->_GetData(i);
nTmp = nOptors = PlgOp1->_GetData(i);
nOptorf += nCflag;
if (nOptorf < nCflag){
_SetData(i ,nOptors);
continue;
}
nOptors -= nOptorf;
if (nOptors > nTmp)
nCflag = 1;
else
nCflag = 0;
_SetData(i ,nOptors);
}
}
1.1.2.下面来看编号为2D70的带符号乘运算,其不是规则的乘运算,主要是控制了结果的长度,其长度由两个操作数的最高位(这里的位指一个4字节整数),经过一定的运算之后决定。同样,我们也直接跟到Small类的该运算,函数有3个参数:
002E21DF 90 nop ; _Mul(Param1 ,Param2 ,nLast)
002E21E0 /$ 83EC 24 sub esp,0x24
002E21E3 |. 55 push ebp
002E21E4 |. 56 push esi
002E21E5 |. 8B7424 38 mov esi,dword ptr ss:[esp+0x38]
002E21E9 |. 57 push edi
002E21EA |. 8BE9 mov ebp,ecx
002E21EC |. 8D7E 1F lea edi,dword ptr ds:[esi+0x1F]
002E21EF |. 896C24 0C mov dword ptr ss:[esp+0xC],ebp
002E21F3 |. C1EF 05 shr edi,0x5
002E21F6 |. 57 push edi
002E21F7 |. 897C24 2C mov dword ptr ss:[esp+0x2C],edi ; nLen = (nLast+0x1f) /32
002E21FB |. E8 00FFFFFF call AppSys.002E2100 ; this->pdata = new dword[edi] 并复制原来内容
002E2200 |. 33C0 xor eax,eax
002E2202 |. 85FF test edi,edi
002E2204 |. 76 10 jbe XAppSys.002E2216
002E2206 |> 8B4D 04 /mov ecx,dword ptr ss:[ebp+0x4] ; -------
002E2209 |. 40 |inc eax
002E220A |. 3BC7 |cmp eax,edi ; <=> memset (this->pdata ,0 ,edi*4)
002E220C |. C74481 FC 0000000>|mov dword ptr ds:[ecx+eax*4-0x4],0x0
002E2214 |.^ 72 F0 \jb XAppSys.002E2206 ; -------
002E2216 |> 8B5424 34 mov edx,dword ptr ss:[esp+0x34]
002E221A |. 8B02 mov eax,dword ptr ds:[edx]
002E221C |. 3BC7 cmp eax,edi
002E221E |. 894424 14 mov dword ptr ss:[esp+0x14],eax
002E2222 |. 76 06 jbe XAppSys.002E222A
002E2224 |. 897C24 14 mov dword ptr ss:[esp+0x14],edi ; nMin1 = nLen < Param1->nValids? nLen : Param1.nValids
002E2228 |. 8BC7 mov eax,edi
002E222A |> 53 push ebx
002E222B |. 33DB xor ebx,ebx
002E222D |. 85C0 test eax,eax
002E222F |. 895C24 30 mov dword ptr ss:[esp+0x30],ebx
002E2233 |. 0F86 49010000 jbe AppSys.002E2382
002E2239 |. 33F6 xor esi,esi
002E223B |. 897424 14 mov dword ptr ss:[esp+0x14],esi ; while (i < nMin1)
002E223F |> 8B4424 38 /mov eax,dword ptr ss:[esp+0x38] ; {
002E2243 |. 8B48 04 |mov ecx,dword ptr ds:[eax+0x4]
002E2246 |. 8B4424 3C |mov eax,dword ptr ss:[esp+0x3C]
002E224A |. 8B00 |mov eax,dword ptr ds:[eax]
002E224C |. 8B1431 |mov edx,dword ptr ds:[ecx+esi]
002E224F |. 03C3 |add eax,ebx ; eax = Param2.nValids + i
002E2251 |. 895424 28 |mov dword ptr ss:[esp+0x28],edx
002E2255 |. 3BC7 |cmp eax,edi ; if (eax > nLen)
002E2257 |. 76 02 |jbe XAppSys.002E225B ; eax = nLen
002E2259 |. 8BC7 |mov eax,edi
002E225B |> 33C9 |xor ecx,ecx
002E225D |. 3BD8 |cmp ebx,eax ; if (i < eax)
002E225F |. 0F83 01010000 |jnb AppSys.002E2366 ; {
002E2265 |. 8B7C24 28 |mov edi,dword ptr ss:[esp+0x28]
002E2269 |. 2BC3 |sub eax,ebx
002E226B |. 81E2 FFFF0000 |and edx,0xFFFF
002E2271 |. 894424 24 |mov dword ptr ss:[esp+0x24],eax ; nTmp24 = eax - i
002E2275 |. C1EF 10 |shr edi,0x10
002E2278 |. 03C3 |add eax,ebx
002E227A |. 897C24 20 |mov dword ptr ss:[esp+0x20],edi ; nTmp20 = HIGH(Param1.GetData(i))
002E227E |. 895424 1C |mov dword ptr ss:[esp+0x1C],edx ; nTmp1C = LOWER(Param1.GetData(i))
002E2282 |. 8BFE |mov edi,esi ; k = i
002E2284 |. 894424 28 |mov dword ptr ss:[esp+0x28],eax
002E2288 |. EB 0C |jmp XAppSys.002E2296 ; for (j = 0,k = i ; nTmp24 > 0 ;j++ ,nTmp2c--,k++)
002E228A |> 8B6C24 10 |/mov ebp,dword ptr ss:[esp+0x10] ; {
002E228E |. 8B5424 1C ||mov edx,dword ptr ss:[esp+0x1C]
002E2292 |. 8B7424 14 ||mov esi,dword ptr ss:[esp+0x14]
002E2296 |> 8BC7 | mov eax,edi
002E2298 |. 2BC6 ||sub eax,esi
002E229A |. 8B7424 3C ||mov esi,dword ptr ss:[esp+0x3C]
002E229E |. 8B76 04 ||mov esi,dword ptr ds:[esi+0x4]
002E22A1 |. 8B1C30 ||mov ebx,dword ptr ds:[eax+esi]
002E22A4 |. 8B45 04 ||mov eax,dword ptr ss:[ebp+0x4]
002E22A7 |. 8BF3 ||mov esi,ebx
002E22A9 |. 8D2C07 ||lea ebp,dword ptr ds:[edi+eax]
002E22AC |. 8B0407 ||mov eax,dword ptr ds:[edi+eax]
002E22AF |. 03C1 ||add eax,ecx ; eax = this->GetDta(k)+cf
002E22B1 |. 3BC1 ||cmp eax,ecx
002E22B3 |. 1BC9 ||sbb ecx,ecx
002E22B5 |. 81E6 FFFF0000 ||and esi,0xFFFF
002E22BB |. 0FAFD6 ||imul edx,esi
002E22BE |. 03C2 ||add eax,edx ; eax += LOWER(Param1.GetData(i))*LOWER(Param2.GetData(j))
002E22C0 |. F7D9 ||neg ecx
002E22C2 |. 3BC2 ||cmp eax,edx
002E22C4 |. 1BD2 ||sbb edx,edx
002E22C6 |. F7DA ||neg edx
002E22C8 |. 03CA ||add ecx,edx
002E22CA |. 8B5424 20 ||mov edx,dword ptr ss:[esp+0x20]
002E22CE |. 0FAFD6 ||imul edx,esi
002E22D1 |. 8BF2 ||mov esi,edx
002E22D3 |. C1E2 10 ||shl edx,0x10 ; eax += (HIGH(Param1.GetData(i))*LOWER(Param2->GetData(j)))<<0x10
002E22D6 |. C1EE 10 ||shr esi,0x10 ; ecx += (HIGH(Param1.GetData(i)) * LOWER(Param2->GetData(j)))>>0x10
002E22D9 |. 03C2 ||add eax,edx
002E22DB |. 03CE ||add ecx,esi
002E22DD |. 3BC2 ||cmp eax,edx
002E22DF |. 1BD2 ||sbb edx,edx
002E22E1 |. F7DA ||neg edx
002E22E3 |. 03CA ||add ecx,edx ; ecx += cf
002E22E5 |. 8BD3 ||mov edx,ebx
002E22E7 |. C1EA 10 ||shr edx,0x10
002E22EA |. 8BF2 ||mov esi,edx
002E22EC |. 0FAF7424 1C ||imul esi,dword ptr ss:[esp+0x1C]
002E22F1 |. 8BDE ||mov ebx,esi
002E22F3 |. C1E6 10 ||shl esi,0x10
002E22F6 |. C1EB 10 ||shr ebx,0x10
002E22F9 |. 03C6 ||add eax,esi ; eax += LOWER(Param1->GetData(i))*HIGH(Param2.GetData(j)) << 0x10
002E22FB |. 03CB ||add ecx,ebx ; ecx += LOWER(Param1->GetData(i))*HIGH(Param2.GetData(j)) >> 0x10
002E22FD |. 3BC6 ||cmp eax,esi
002E22FF |. 8945 00 ||mov dword ptr ss:[ebp],eax ; _SetData(k ,eax)
002E2302 |. 1BF6 ||sbb esi,esi
002E2304 |. 0FAF5424 20 ||imul edx,dword ptr ss:[esp+0x20] ; edx = HIGH(Param1->GetData(i))* HIGH(Param2.GetData(j))
002E2309 |. 8B4424 24 ||mov eax,dword ptr ss:[esp+0x24]
002E230D |. 03D1 ||add edx,ecx
002E230F |. F7DE ||neg esi
002E2311 |. 83C7 04 ||add edi,0x4
002E2314 |. 48 ||dec eax
002E2315 |. 8D0C32 ||lea ecx,dword ptr ds:[edx+esi] ; ecx += edx + cf ecx是进位值
002E2318 |. 894424 24 ||mov dword ptr ss:[esp+0x24],eax
002E231C |.^ 0F85 68FFFFFF |\jnz AppSys.002E228A ; }
002E2322 |. 85C9 |test ecx,ecx
002E2324 |. 74 30 |je XAppSys.002E2356
002E2326 |> 8B5424 28 |/mov edx,dword ptr ss:[esp+0x28] ; while ( ecx != 0)
002E232A |. 8B4424 2C ||mov eax,dword ptr ss:[esp+0x2C] ; {
002E232E |. 3BD0 ||cmp edx,eax
002E2330 |. 73 24 ||jnb XAppSys.002E2356 ; if (k >= nLen)
002E2332 |. 8B7424 10 ||mov esi,dword ptr ss:[esp+0x10] ; break;
002E2336 |. 8B46 04 ||mov eax,dword ptr ds:[esi+0x4]
002E2339 |. 8B2C90 ||mov ebp,dword ptr ds:[eax+edx*4]
002E233C |. 8D0490 ||lea eax,dword ptr ds:[eax+edx*4]
002E233F |. 03E9 ||add ebp,ecx
002E2341 |. 8928 ||mov dword ptr ds:[eax],ebp ; this.Pdata[k] += ecx
002E2343 |. 8B46 04 ||mov eax,dword ptr ds:[esi+0x4] ; ecx = cf
002E2346 |. 390C90 ||cmp dword ptr ds:[eax+edx*4],ecx
002E2349 |. 1BC9 ||sbb ecx,ecx
002E234B |. F7D9 ||neg ecx
002E234D |. 42 ||inc edx
002E234E |. 85C9 ||test ecx,ecx
002E2350 |. 895424 28 ||mov dword ptr ss:[esp+0x28],edx
002E2354 |.^ 75 D0 |\jnz XAppSys.002E2326 ; }
002E2356 |> 8B6C24 10 |mov ebp,dword ptr ss:[esp+0x10]
002E235A |. 8B7C24 2C |mov edi,dword ptr ss:[esp+0x2C]
002E235E |. 8B5C24 30 |mov ebx,dword ptr ss:[esp+0x30]
002E2362 |. 8B7424 14 |mov esi,dword ptr ss:[esp+0x14] ; }
002E2366 |> 8B4424 18 |mov eax,dword ptr ss:[esp+0x18]
002E236A |. 43 |inc ebx ; i++
002E236B |. 83C6 04 |add esi,0x4
002E236E |. 3BD8 |cmp ebx,eax
002E2370 |. 895C24 30 |mov dword ptr ss:[esp+0x30],ebx
002E2374 |. 897424 14 |mov dword ptr ss:[esp+0x14],esi
002E2378 |.^ 0F82 C1FEFFFF \jb AppSys.002E223F ; }
002E237E |. 8B7424 40 mov esi,dword ptr ss:[esp+0x40]
002E2382 |> 83E6 1F and esi,0x1F
002E2385 |. 5B pop ebx
002E2386 |. 74 17 je XAppSys.002E239F ; if (nLast&0x1F != 0)
002E2388 |. 8B4D 04 mov ecx,dword ptr ss:[ebp+0x4] ; {
002E238B |. BA 01000000 mov edx,0x1
002E2390 |. 8D44B9 FC lea eax,dword ptr ds:[ecx+edi*4-0x4]
002E2394 |. 8BCE mov ecx,esi
002E2396 |. D3E2 shl edx,cl
002E2398 |. 8B08 mov ecx,dword ptr ds:[eax]
002E239A |. 4A dec edx
002E239B |. 23CA and ecx,edx ; this.Pdata[nLen-1] += 2^(nLast&0x1f) -1
002E239D |. 8908 mov dword ptr ds:[eax],ecx ; }
002E239F |> 85FF test edi,edi
002E23A1 |. 74 14 je XAppSys.002E23B7
002E23A3 |. 8B45 04 mov eax,dword ptr ss:[ebp+0x4]
002E23A6 |. 8D44B8 FC lea eax,dword ptr ds:[eax+edi*4-0x4] ; ---------
002E23AA |> 8338 00 /cmp dword ptr ds:[eax],0x0
002E23AD |. 75 08 |jnz XAppSys.002E23B7
002E23AF |. 4F |dec edi ; 重新计算nValids值
002E23B0 |. 83E8 04 |sub eax,0x4
002E23B3 |. 85FF |test edi,edi
002E23B5 |.^ 75 F3 \jnz XAppSys.002E23AA
002E23B7 |> 897D 00 mov dword ptr ss:[ebp],edi ; ----------
002E23BA |. 5F pop edi
002E23BB |. 5E pop esi
002E23BC |. 5D pop ebp
002E23BD |. 83C4 24 add esp,0x24
002E23C0 \. C2 0C00 retn 0xC
因为即使如果将两个4字节的整数直接相乘都有可能溢出,更不要说无限大的整数。因此这里采用一种方法求2个4字节整数的积,结果分为高位与低位:
低位 nLow = LOW(op1)*LOW(op2) + (HIGH(OP1)*LOW(OP2)) << 0X10 + (LOW(OP1)*HIGH(OP2)) << 0x10
高位 nHigh = (HIGH(OP1)*LOW(OP2))>>0x10 + (LOW(OP1)*HIGH(OP2)>>0x10) +
HIGH(P1)*HIGH(OP2) + 每次低位nLow加得一个数之后的cf;
对应的C++代码如下,同样,里面的一大部分函数就不分析了,直接看下面的C++代码:
void LargeInt::_SignedMulVariant(
LargeInt* PlgOp1,
LargeInt* PlgOp2
)
{
_UnSignedMulVariant(PlgOp1 ,PlgOp2 ,0);
if (PlgOp1->_GetSignFlags() == PlgOp2->_GetSignFlags())
nSignFlag = 0;
else
nSignFlag = 1;
}
void LargeInt::_UnSignedMulVariant(
LargeInt* PlgOp1,
LargeInt* PlgOp2,
unsigned int nInitLast
)
{
unsigned int nLast = nInitLast ? nInitLast : (PlgOp1->_CalcLastData() + PlgOp2->_CalcLastData()) ;
nLast = (nLast + 0x1F) >> 0x5;
unsigned int nMin = (nLast < PlgOp1->_GetValids())? nLast : (PlgOp1->_GetValids());
_Zero();
unsigned int nOptorf ,nOptors ,nHighLast ,nHighNext ,nLow ,nMulty ,nEax;
for (unsigned int i = 0 ;i < nMin ;i++)
{
nEax = i + PlgOp2->_GetValids();
if (nEax > nLast)
nEax = nLast;
if (i < nEax)
{
nLow = nHighLast = nHighNext = 0;
for (unsigned int j = 0 ,nCnt = nEax - i ,nLoc = i ;nCnt > 0 ;j++ ,nCnt-- ,nLoc++)
{
nOptorf = PlgOp1->_GetData(i);
nOptors = PlgOp2->_GetData(j);
nLow = _GetData(nLoc);
nLow += nHighLast;
if (nLow < nHighLast)
nHighNext++;
nMulty = (unsigned int)LOWORD(nOptorf) * (unsigned int)LOWORD(nOptors);
nLow += nMulty;
if (nLow < nMulty)
nHighNext++;
nMulty = (unsigned int)LOWORD(nOptorf) * (unsigned int)HIWORD(nOptors);
nHighNext += (nMulty>>0x10);
nMulty <<= 0x10;
nLow += nMulty;
if (nLow < nMulty)
nHighNext++;
nMulty = (unsigned int)HIWORD(nOptorf) * (unsigned int)LOWORD(nOptors);
nHighNext += (nMulty>>0x10);
nMulty <<= 0x10;
nLow += nMulty;
if (nLow < nMulty)
nHighNext++;
nMulty = (unsigned int)HIWORD(nOptorf) * (unsigned int)HIWORD(nOptors);
nHighNext += nMulty;
_SetData(nLoc ,nLow);
nHighLast = nHighNext;
nLow = nHighNext = 0;
}
while (nHighLast)
{
nLow = nHighLast + _GetData(nLoc);
if (nLow < nHighLast)
nHighLast = 1;
else
nHighLast = 0;
if (nLoc >= nLast)
break;
_SetData(nLoc++ ,nLow);
}
}//end of if
}//end of for()
unsigned int nEsi = nInitLast ? (nInitLast&0x1f):((PlgOp1->_CalcLastData() + PlgOp2->_CalcLastData()) & 0x1F);
if (nEsi)
{
unsigned int nTmp = 1;
nTmp <<= nEsi;
_SetData(nLast-1 ,(nTmp-1)&_GetData(nLast-1));
}
}
unsigned int LargeInt::_CalcLastData(
)
{
if (!nValids)
return 0;
unsigned int nLast = _GetData(nValids-1);
unsigned int nRet = ((nValids + 0x7FFFFFF)<<0x5);
unsigned int nEcx = 0x20 ,nTmp = 1;
while (nEcx > 0x8)
{
nEcx >>= 0x1;
if (nLast > (nTmp<<nEcx))
{
nRet += nEcx;
nLast >>= nEcx;
}
}
nTmp = 1;
for (int i = 0 ;i <= 9 ;i++)
{
if ((nTmp<<i) > nLast)
{
nRet += i;
break;
}
}
return nRet;
}
这篇就先写到这里,还没分析完,接下来的请看下一篇吧:Ultra Video Joiner注册分析 附 注册机(下)
未完待续..........
[课程]Android-CTF解题方法汇总!