发现在Exports中有tlscallback,好了,我们首先看看在tls中做了什么?
函数 401A10 为真正的check函数,其调用 sub_401290函数,如果 sub_401290函数返回1,则起再次计算输入sn的hash值,并判断此hash值是否等于0x5634D252,如果相等,则将全局字串改为; "try again!"改为success'" ,"fail"改为 "ok"。
将可执行文件拖入Ida分析,可以看到WinMain()入口函数如下:
int __stdcall WinMain()
{
sub_401280();
return 0;
}
void sub_401280()
{
;
}
int __stdcall WinMain()
{
sub_401280();
return 0;
}
void sub_401280()
{
;
}
程序sub_401280()是一个空函数,看来有其他奥妙了。
发现在Exports中有tlscallback,好了,我们首先看看在tls中做了什么?
HANDLE __stdcall TlsCallback_0(int a1, int a2, int a3)
{
HANDLE result; // eax
int Parameter; // [esp+Ch] [ebp-8h]
int v5; // [esp+10h] [ebp-4h]
result = (HANDLE)0xCCCCCCCC;
Parameter = 0xCCCCCCCC;
v5 = 0xCCCCCCCC;
if ( a2 == 1 )
{
sub_401D50();
InitializeCriticalSection(&CriticalSection);
sub_401C10();
result = CreateThread(0, 0, StartAddress, &Parameter, 0, 0);
}
return result;
}
int sub_401D50()
{
signed int i; // [esp+0h] [ebp-18h]
int v2[3]; // [esp+Ch] [ebp-Ch]
v2[1] = 0xCCCCCCCC;
v2[2] = 0xCCCCCCCC;
v2[0] = 0xE9;
*(int *)((char *)v2 + 1) = (char *)off_414014 - (char *)((_BYTE *)off_414018 + 4) - 5; //组织jmp指令
sub_4019B0(off_414018);
for ( i = 0; i < 5; ++i )
*((_BYTE *)off_414018 + i + 4) = *((_BYTE *)v2 + i); //插入jmp指令
return sub_4019E0(off_414018);
}
.data:00414014 off_414014 dd offset sub_401220 ; DATA XREF: sub_401D50+45↑r
.data:00414018 off_414018 dd offset sub_401280 ; DATA XREF: sub_401D50+3D↑r
可以看到:
全局变量off_414018存储着sub_401280()函数地址,而该函数就是
WinMain()中那个空函数地址。
全局变量off_414018存储着
sub_401220()
这里在
sub_401280()中插入了
sub_401220()函数调用。修改前后对比如下图:
sub_11220()函数如下:
void __noreturn sub_401220()
{
HINSTANCE hInstance; // ST18_4
hInstance = GetModuleHandleW(0);
DialogBoxParamW(hInstance, (LPCWSTR)0x65, 0, DialogFunc, 0);
exit(0);
}
我们暂时先放下TLS分析,看看DialogFunc()函数,在该函数里主要是调用了sub_401040()这个函数。
int __cdecl sub_401040(HWND hDlg)
{
void *v1; // ST08_4
signed int i; // [esp+Ch] [ebp-24h]
signed int v4; // [esp+10h] [ebp-20h]
CHAR String; // [esp+18h] [ebp-18h]
int v6; // [esp+19h] [ebp-17h]
int v7; // [esp+1Dh] [ebp-13h]
int v8; // [esp+21h] [ebp-Fh]
int v9; // [esp+25h] [ebp-Bh]
__int16 v10; // [esp+29h] [ebp-7h]
char v11; // [esp+2Bh] [ebp-5h]
strcpy(Text, "try again!"); // //看到了,我们验证失败时候的字串
strcpy(Caption, "fail");
String = 0;
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
GetDlgItemTextA(hDlg, 1001, &String, 20);
v4 = 0;
for ( i = 0; i < 20; ++i )
v4 += *(&String + i);
if ( v4 > 0 && v4 < 4132 )
{
v1 = malloc(v4);
sub_401020();
j___free_base(v1);
}
return MessageBoxA(0, Text, Caption, 0);
}
然而sub_401020()函数又是一个空函数,带着这个问题,我们继续分析TLS后面的内容。
2.分析sub_401C10()函数
int sub_401C10()
{
void *v0; // edx
signed int j; // [esp+0h] [ebp-Ch]
signed int i; // [esp+8h] [ebp-4h]
sub_4018D0();
lpAddress = v0;
sub_4019B0(v0);
for ( i = 0; i < 5; ++i )
byte_4147DC[i] = *((_BYTE *)lpAddress + i + 32);
*(_DWORD *)&byte_414028[1] = (char *)sub_401A10 - (char *)((_BYTE *)lpAddress + 32) - 5;
for ( j = 0; j < 5; ++j )
*((_BYTE *)lpAddress + j + 32) = byte_414028[j];
return sub_4019E0(lpAddress);
}
这个函数看着和上一个函数很像,关键是v0(edx)指向的是什么地址呢?v0中的值看上去应该是 sub_4018D0()初始化的。先来看看这个函数。
分析这个函数之前我们先来温习点功课:FS段寄存器,TEB结构,PEB结构
1)FS段寄存器指向当前的TEB结构,在TEB编译0x30处是PEB指针,通过这个指针即可获得PED的地址。
2)
TEB和PEB的结构如下:
typedef struct _NT_TIB
{ // Size: 01C
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 000
PVOID StackBase; // 004
PVOID StackLimit; // 008
PVOID SubSystemTib; // 00C
union // 010
{
PVOID FiberData;
ULONG Version;
};
PVOID ArbitraryUserPointer; // 014
struct _NT_TIB *Self; // 018
} NT_TIB, *PNT_TIB;
typedef struct _TEB
{ // Size: FBC
NT_TIB Tib; // 000
PVOID EnvironmentPointer; // 01C
CLIENT_ID Cid; // 020
PVOID ActiveRpcHandle; // 028
PVOID ThreadLocalStoragePointer; // 02C
struct _PEB *ProcessEnvironmentBlock; // 030
ULONG LastErrorValue; // 034
ULONG CountOfOwnedCriticalSections; // 038
PVOID CsrClientThread; // 03C
struct _W32THREAD* Win32ThreadInfo; // 040
ULONG User32Reserved[0x1A]; // 044
ULONG UserReserved[5]; // 0AC
PVOID WOW32Reserved; // 0C0
LCID CurrentLocale; // 0C4
ULONG FpSoftwareStatusRegister; // 0C8
PVOID SystemReserved1[0x36]; // 0CC
LONG ExceptionCode; // 1A4
struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; // 1A8
UCHAR SpareBytes1[0x28]; // 1AC
GDI_TEB_BATCH GdiTebBatch; // 1D4
CLIENT_ID RealClientId; // 6B4
PVOID GdiCachedProcessHandle; // 6BC
ULONG GdiClientPID; // 6C0
ULONG GdiClientTID; // 6C4
PVOID GdiThreadLocalInfo; // 6C8
ULONG Win32ClientInfo[62]; // 6CC
PVOID glDispatchTable[0xE9]; // 7C4
ULONG glReserved1[0x1D]; // B68
PVOID glReserved2; // BDC
PVOID glSectionInfo; // BE0
PVOID glSection; // BE4
PVOID glTable; // BE8
PVOID glCurrentRC; // BEC
PVOID glContext; // BF0
NTSTATUS LastStatusValue; // BF4
UNICODE_STRING StaticUnicodeString; // BF8
WCHAR StaticUnicodeBuffer[0x105]; // C00
PVOID DeallocationStack; // E0C
PVOID TlsSlots[0x40]; // E10
LIST_ENTRY TlsLinks; // F10
PVOID Vdm; // F18
PVOID ReservedForNtRpc; // F1C
PVOID DbgSsReserved[0x2]; // F20
ULONG HardErrorDisabled; // F28
PVOID Instrumentation[14]; // F2C
PVOID SubProcessTag; // F64
PVOID EtwTraceData; // F68
PVOID WinSockData; // F6C
ULONG GdiBatchCount; // F70
BOOLEAN InDbgPrint; // F74
BOOLEAN FreeStackOnTermination; // F75
BOOLEAN HasFiberData; // F76
UCHAR IdealProcessor; // F77
ULONG GuaranteedStackBytes; // F78
PVOID ReservedForPerf; // F7C
PVOID ReservedForOle; // F80
ULONG WaitingOnLoaderLock; // F84
ULONG SparePointer1; // F88
ULONG SoftPatchPtr1; // F8C
ULONG SoftPatchPtr2; // F90
PVOID *TlsExpansionSlots; // F94
ULONG ImpersionationLocale; // F98
ULONG IsImpersonating; // F9C
PVOID NlsCache; // FA0
PVOID pShimData; // FA4
ULONG HeapVirualAffinity; // FA8
PVOID CurrentTransactionHandle; // FAC
PTEB_ACTIVE_FRAME ActiveFrame; // FB0
PVOID FlsData; // FB4
UCHAR SafeThunkCall; // FB8
UCHAR BooleanSpare[3]; // FB9
} TEB, *PTEB;
typedef struct _LIST_ENTRY
{ // Size: 008
struct _LIST_ENTRY *Flink; // 000 从前到后
struct _LIST_ENTRY *Blink; // 004 从后到前
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _PER_LDR_DATA
{ // Size: 0024
ULONG Length; // 000
BOOLEAN Initialize; // 004
PVOID SsHandle; // 008
LIST_ENTRY InLoadOrderModuleList; // 00C
LIST_ENTRY InMemoryOrderModuleList; // 014
LIST_ENTRY InInitializationOrderModuleList; // 01C
} PER_LDR_DATA, *PPER_LDR_DATA;
typedef struct _UNICODE_STRING
{ // Size: 008
USHORT Length; // 000 占用的内存字节数,个数*2;
USHORT MaximumLength; // 002
PWSTR Buffer; // 004
} UNICODE_STRING ,*PUNICODE_STRING;
typedef struct _LDR_DATA_TABLE_ENTRY
{ // Size: 050
LIST_ENTRY InLoadOrderLinks; // 000 LIST_ENTRY里的Flink和Blink其实是指向LDR_MODULE结构,即LDR_DATA_TABLE_ENTRY
LIST_ENTRY InMemoryOrderLinks; // 008 同上
LIST_ENTRY InInitializationOrderLinks; // 010 同上
PVOID DllBase; // 018
PVOID EntryPoint; // 01C
ULONG SizeOfImage; // 020
UNICODE_STRING FullDllName; // 024
UNICODE_STRING BaseDllName; // 02C
ULONG Flags; // 034
WORD LoadCount; // 038
WORD TlsIndex; // 03A
union // 03C
{
LIST_ENTRY HashLinks; // 03C
struct
{
PVOID SectionPointer; // 03C
ULONG CheckSum; // 040
};
};
union
{
ULONG TimeDateStamp; // 044
PVOID LoadedImports; // 044
};
_ACTIVATION_CONTEXT * EntryPointActivationContext; // 048
PVOID PatchInformation; // 04C
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB
{ // Size: 1D8
UCHAR InheritedAddressSpace; // 000
UCHAR ReadImageFileExecOptions; // 001
UCHAR BeingDebugged; // 002
UCHAR SpareBool; // 003 Allocation size
HANDLE Mutant; // 004
HINSTANCE ImageBaseAddress; // 008
struct _PER_LDR_DATA *Ldr; // 00C
strcut _RTL_USER_PPROCESS_PARAMETERS *ProcessParameters; // 010
ULONG SubSystemData; // 014
HANDLE DefaultHeap; // 018
KSPIN_LOCK FastPebLock; // 01C
ULONG FastPebLockRoutine; // 020
ULONG FastPebUnlockRoutine; // 024
ULONG EnvironmentUpdateCount; // 028
ULONG KernelCallbackTable; // 02C
LARGE_INTEGER SystemReserved; // 030
struct _PER_FREE_BLOCK *FreeList; // 038
ULONG TlsExpansionCounter; // 03C
ULONG TlsBitmap; // 040
LARGE_INTEGER TlsBitmapBits; // 044
ULONG ReadOnlySharedMemoryBase; // 04C
ULONG ReadOnlySharedMemoryHeap; // 050
ULONG ReadOnlyStaticServerData; // 054
ULONG AnsiCodePageData; // 058
ULONG OemCodePageData; // 05C
ULONG UnicodeCaseTableData; // 060
ULONG NumberOfProcessors; // 064
LARGE_INTEGER NtGlobalFlag; // 068 Address of a local copy
LARGE_INTEGER CriticalSectionTimeout; // 070
ULONG HeapSegmentReserve; // 078
ULONG HeapSegmentCommit; // 07C
ULONG HeapDeCommitTotalFreeThreshold; // 080
ULONG HeapDeCommitFreeBlockThreshold; // 084
ULONG NumberOfHeaps; // 088
ULONG MaximumNumberOfHeaps; // 08C
ULONG ProcessHeaps; // 090
ULONG GdiSharedHandleTable; // 094
ULONG ProcessStarterHelper; // 098
ULONG GdiDCAttributeList; // 09C
KSPIN_LOCK LoaderLock; // 0A0
ULONG OSMajorVersion; // 0A4
ULONG OSMinorVersion; // 0A8
USHORT OSBuildNumber; // 0AC
USHORT OSCSDVersion; // 0AE
ULONG OSPlatformId; // 0B0
ULONG ImageSubsystem; // 0B4
ULONG ImageSubsystemMajorVersion; // 0B8
ULONG ImageSubsystemMinorVersion; // 0BC
ULONG ImageProcessAffinityMask; // 0C0
ULONG GdiHandleBuffer[0x22]; // 0C4
ULONG PostProcessInitRoutine; // 14C
ULONG TlsExpansionBitmap; // 150
UCHAR TlsExpansionBitmapBits[0x80]; // 154
ULONG SessionId; // 1D4
} PEB, *PPEB;
好了有了TEB,PEB数据结构的支撑,我们来分析
sub_4018D0()函数
int sub_4018D0()
{
int v0; // edx
sub_4018F5(0x3BD696F4);
return sub_401928(v0, 0x925DF53F);
}
0x3BD696F4是目标字串hash值,继续分析 sub_4018F5()
int __stdcall sub_4018F5(int hash)
{
int hash_1; // ecx
_DWORD *v2; // esi
int hash_2; // ST08_4
int v4; // ST04_4
int len; // eax
int result; // eax
int v7; // edx
hash_1 = hash;
v2 = *(_DWORD **)(*(_DWORD *)(__readfsdword(0x30u) + 0xC) + 0x1C);// v2 = LIST_ENTRY InInitializationOrderModuleList;
do
{
v2 = (_DWORD *)*v2;
hash_2 = hash_1;
v4 = v2[6]; // 获取FullDllName;
len = strlen(v2[6]); // 计算字符串长度
result = getHash(v4, 2 * len); // 计算hash
hash_1 = hash_2;
}
while ( result != hash_2 );
v7 = v2[2]; // 获得指定dll基址(DllBase)
return result;
0x30处是PEB的指针 :struct _PEB *ProcessEnvironmentBlock;// 030
PEB+0xc处的指针 :struct _PER_LDR_DATA *Ldr;// 00C
Ldr +0x1c处的指针 :LIST_ENTRY InInitializationOrderModuleList;
目标动态库:C:\Windows\syswow64\USER32.dll 基址存储在edx中
可以看到sub_4018F5(int hash)是根据指定hash获得动态库基址。将DLL基址和目标函数hash传入sub_401928()函数,
继续分析
int __stdcall sub_401928(int dllbase, int funcHash)
{
_DWORD *v2; // esi
int i; // eax
int v4; // esi
int v5; // eax
int v7; // [esp-8h] [ebp-14h]
int v8; // [esp+0h] [ebp-Ch]
int v9; // [esp+4h] [ebp-8h]
int v10; // [esp+8h] [ebp-4h]
v2 = (_DWORD *)(dllbase + *(_DWORD *)(dllbase + *(_DWORD *)(dllbase + 0x3C) + 0x78));
v10 = v2[7];
v9 = v2[8];
v8 = v2[9];
for ( i = 0; ; i = v7 + 1 )
{
v4 = dllbase + *(_DWORD *)(dllbase + v9 + 4 * i);
v7 = i;
v5 = sub_401870(dllbase + *(_DWORD *)(dllbase + v9 + 4 * i));
if ( getHash(v4, v5) == funcHash )
break;
}
return dllbase + *(_DWORD *)(dllbase + v10 + 4 * *(unsigned __int16 *)(dllbase + v8 + 2 * v7));
}
该函数返回目标函数地址,目标函数为:GetDlgItemTextA()
这样找到了lpAddress指向的地址
GetDlgItemTextA()。我们看一下sub_401c10()函数修改后 GetDlgItemTextA()的情况
user32_GetDlgItemTextA proc near
user32.dll:76326BCE
user32.dll:76326BCE arg_0= dword ptr 8
user32.dll:76326BCE arg_4= dword ptr 0Ch
user32.dll:76326BCE arg_8= dword ptr 10h
user32.dll:76326BCE arg_C= dword ptr 14h
user32.dll:76326BCE
user32.dll:76326BCE 8B FF mov edi, edi
user32.dll:76326BD0 55 push ebp
user32.dll:76326BD1 8B EC mov ebp, esp
user32.dll:76326BD3 FF 75 0C push [ebp+arg_4]
user32.dll:76326BD6 FF 75 08 push [ebp+arg_0]
user32.dll:76326BD9 E8 7C CB FA FF call near ptr user32_GetDlgItem
user32.dll:76326BDE 85 C0 test eax, eax
user32.dll:76326BE0 74 0E jz short near ptr loc_76326BEE+2
user32.dll:76326BE2 FF 75 14 push [ebp+arg_C]
user32.dll:76326BE5 FF 75 10 push [ebp+arg_8]
user32.dll:76326BE8 50 push eax
user32.dll:76326BE9 E8 53 94 FA FF call near ptr user32_GetWindowTextA
user32.dll:76326BEE
user32.dll:76326BEE loc_76326BEE: ; CODE XREF: user32_GetDlgItemTextA+12↑j
user32.dll:76326BEE E9 1D AE CE 89 jmp sub_11A10
在执行
GetDlgItemTextA()后会jmp 到sub_11A10()执行。我们翻回头在看
DialogFunc ,TLS并没有对sub_401020()做什么,而是在
GetDlgItemTextA()函数尾hook了该函数,转而执行
sub_11A10()。
int __usercall sub_401A10@<eax>(int a1@<ecx>, int a2@<ebp>, int a3@<esi>)
{
unsigned int v3; // et0
int v4; // eax
_BYTE *v5; // ecx
unsigned int v7; // [esp-24h] [ebp-24h]
int v8; // [esp-18h] [ebp-18h]
v8 = a1;
v3 = __readeflags();
v7 = v3;
dword_414800 = a3;
dword_4147EC = *(_DWORD *)(a2 + 20);
dword_4147F0 = malloc(dword_4147EC);
dword_4147F4 = a2 + 16;
memmove(dword_4147F0, *(const void **)(a2 + 16), dword_4147EC);
*(_DWORD *)(a2 - 16) = dword_4147F0;
*(_DWORD *)(a2 - 20) = *(_DWORD *)(a2 - 16) + 1;
do
*(_BYTE *)(a2 - 21) = *(_BYTE *)(*(_DWORD *)(a2 - 16))++;
while ( *(_BYTE *)(a2 - 21) );
*(_DWORD *)(a2 - 28) = *(_DWORD *)(a2 - 16) - *(_DWORD *)(a2 - 20);
if ( (unsigned __int8)sub_401290((int)dword_4147F0, *(_DWORD *)(a2 - 28)) )
{
v4 = sub_401870((int)dword_4147F0);
if ( getHash((int)dword_4147F0, v4) == 1446302290 )
{
v5 = off_414030;
*(_WORD *)off_414030 = 0;
v5[2] = 0;
for ( *(_WORD *)(a2 - 4) = 0; *(signed __int16 *)(a2 - 4) < 8; ++*(_WORD *)(a2 - 4) )
*((char *)off_414030 - *(signed __int16 *)(a2 - 4)) = (39 - *(unsigned __int16 *)(a2 - 4)) ^ byte_41401C[7 - *(signed __int16 *)(a2 - 4)];
*(_WORD *)off_414034 = 0;
for ( *(_WORD *)(a2 - 8) = 0; *(signed __int16 *)(a2 - 8) < 3; ++*(_WORD *)(a2 - 8) )
*((char *)off_414034 - *(signed __int16 *)(a2 - 8)) = (34 - *(unsigned __int16 *)(a2 - 8)) ^ byte_414024[2 - *(signed __int16 *)(a2 - 8)];
}
}
j___free_base(dword_4147F0);
dword_4147F8 = (int (__thiscall *)(_DWORD))((char *)lpAddress + 32);
sub_4019B0(lpAddress);
for ( *(_DWORD *)(a2 - 12) = 0; *(_DWORD *)(a2 - 12) < 5; ++*(_DWORD *)(a2 - 12) )
*((_BYTE *)lpAddress + *(_DWORD *)(a2 - 12) + 32) = byte_4147DC[*(_DWORD *)(a2 - 12)];
sub_4019E0(lpAddress);
dword_4147FC = 1;
__writeeflags(v7);
return dword_4147F8(v8);
}
到此TLS函数分析完成。
函数 401A10 为真正的check函数,其调用 sub_401290函数,如果 sub_401290函数返回1,则起再次计算输入sn的hash值,并判断此hash值是否等于0x5634D252,如果相等,则将全局字串改为; "try again!"改为success'" ,"fail"改为 "ok"。
3、判定程序
程序的主要判断逻辑在sub_401290()中
bool __cdecl sub_401290(char *sn, int len)
{
byte_4147D0[0] = 4;
byte_4147D0[1] = 1;
byte_4147D0[2] = 3;
byte_4147D0[3] = 7;
byte_4147D0[4] = 2;
byte_4147D0[5] = 5;
byte_4147D0[6] = 8;
byte_4147D0[7] = 6;
byte_4147D0[8] = 0;
return sub_4015B0(sn, len);
}
bool __cdecl sub_4015B0(char *sn, int len)
{
int i; // [esp+0h] [ebp-Ch]
signed int v4; // [esp+8h] [ebp-4h]
v4 = 0xCCCCCCCC;
if ( len % 2 )
return 0;
for ( i = 0; i < len; i += 2 )
{
if ( sn[i] == 'w' )
v4 = 0;
if ( sn[i] == 'd' )
v4 = 1;
if ( sn[i] == 's' )
v4 = 2;
if ( sn[i] == 'a' )
v4 = 3;
if ( !(unsigned __int8)sub_401380(v4, sn[i + 1] - 48) )
return 0;
}
return byte_4147D0[0] == 1
&& byte_4147D0[1] == 2
&& byte_4147D0[2] == 3
&& byte_4147D0[3] == 4
&& byte_4147D0[4] == 5
&& byte_4147D0[5] == 6
&& byte_4147D0[6] == 7
&& byte_4147D0[7] == 8
&& !byte_4147D0[8];
}
char __cdecl sub_401380(int a1, int a2)
{
char result; // al
signed int i; // [esp+8h] [ebp-8h]
signed int v4; // [esp+Ch] [ebp-4h]
if ( !a2 )
return 0;
v4 = 0;
LABEL_4:
if ( v4 >= 3 )
return 0;
for ( i = 0; ; ++i )
{
if ( i >= 3 )
{
++v4;
goto LABEL_4;
}
if ( byte_4147D0[3 * v4 + i] == a2 )
break;
LABEL_6:
;
}
switch ( a1 )
{
case 0:
if ( v4 )
{
if ( byte_4147D0[3 * (v4 - 1) + i] )
{
result = 0;
}
else
{
byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i];
byte_4147D0[3 * v4 + i] = 0;
result = 1;
}
}
else
{
result = 0;
}
break;
case 1:
if ( i == 2 )
{
result = 0;
}
else if ( byte_4147D1[3 * v4 + i] )
{
result = 0;
}
else
{
byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i];
byte_4147D0[3 * v4 + i] = 0;
result = 1;
}
break;
case 2:
if ( v4 == 2 )
{
result = 0;
}
else if ( byte_4147D0[3 * (v4 + 1) + i] )
{
result = 0;
}
else
{
byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i];
byte_4147D0[3 * v4 + i] = 0;
result = 1;
}
break;
case 3:
if ( i )
{
if ( byte_4147CF[3 * v4 + i] )
{
result = 0;
}
else
{
byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i];
byte_4147D0[3 * v4 + i] = 0;
result = 1;
}
}
else
{
result = 0;
}
break;
default:
goto LABEL_6;
}
return result;
}
sub_401290函数初始化为char 4147D0[9] = {4,1,3,7,2,5,8,6,0}; 调用sub_4015B0函数根据输入sn对
4147D0[9]内容进行调整(加密)后,如果
char 4147D0[9]值变为
{1,2,3,4,5,6,7,8,0},则成功。算法类似一个简单的华容道,路线如下图:
flag:d6d8s7s4a1w2a5w6
HANDLE __stdcall TlsCallback_0(int a1, int a2, int a3)
{
HANDLE result; // eax
int Parameter; // [esp+Ch] [ebp-8h]
int v5; // [esp+10h] [ebp-4h]
result = (HANDLE)0xCCCCCCCC;
Parameter = 0xCCCCCCCC;
v5 = 0xCCCCCCCC;
if ( a2 == 1 )
{
sub_401D50();
InitializeCriticalSection(&CriticalSection);
sub_401C10();
result = CreateThread(0, 0, StartAddress, &Parameter, 0, 0);
}
return result;
}
int sub_401D50()
{
signed int i; // [esp+0h] [ebp-18h]
int v2[3]; // [esp+Ch] [ebp-Ch]
v2[1] = 0xCCCCCCCC;
v2[2] = 0xCCCCCCCC;
v2[0] = 0xE9;
*(int *)((char *)v2 + 1) = (char *)off_414014 - (char *)((_BYTE *)off_414018 + 4) - 5; //组织jmp指令
sub_4019B0(off_414018);
for ( i = 0; i < 5; ++i )
*((_BYTE *)off_414018 + i + 4) = *((_BYTE *)v2 + i); //插入jmp指令
return sub_4019E0(off_414018);
}
.data:00414014 off_414014 dd offset sub_401220 ; DATA XREF: sub_401D50+45↑r
.data:00414018 off_414018 dd offset sub_401280 ; DATA XREF: sub_401D50+3D↑r
.data:00414014 off_414014 dd offset sub_401220 ; DATA XREF: sub_401D50+45↑r
.data:00414018 off_414018 dd offset sub_401280 ; DATA XREF: sub_401D50+3D↑r
可以看到:
全局变量off_414018存储着sub_401280()函数地址,而该函数就是
WinMain()中那个空函数地址。
全局变量off_414018存储着
sub_401220()
这里在
sub_401280()中插入了
sub_401220()函数调用。修改前后对比如下图:
sub_11220()函数如下:
void __noreturn sub_401220()
{
HINSTANCE hInstance; // ST18_4
hInstance = GetModuleHandleW(0);
DialogBoxParamW(hInstance, (LPCWSTR)0x65, 0, DialogFunc, 0);
exit(0);
}
void __noreturn sub_401220()
{
HINSTANCE hInstance; // ST18_4
hInstance = GetModuleHandleW(0);
DialogBoxParamW(hInstance, (LPCWSTR)0x65, 0, DialogFunc, 0);
exit(0);
}
我们暂时先放下TLS分析,看看DialogFunc()函数,在该函数里主要是调用了sub_401040()这个函数。
int __cdecl sub_401040(HWND hDlg)
{
void *v1; // ST08_4
signed int i; // [esp+Ch] [ebp-24h]
signed int v4; // [esp+10h] [ebp-20h]
CHAR String; // [esp+18h] [ebp-18h]
int v6; // [esp+19h] [ebp-17h]
int v7; // [esp+1Dh] [ebp-13h]
int v8; // [esp+21h] [ebp-Fh]
int v9; // [esp+25h] [ebp-Bh]
__int16 v10; // [esp+29h] [ebp-7h]
char v11; // [esp+2Bh] [ebp-5h]
strcpy(Text, "try again!"); // //看到了,我们验证失败时候的字串
strcpy(Caption, "fail");
String = 0;
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
GetDlgItemTextA(hDlg, 1001, &String, 20);
v4 = 0;
for ( i = 0; i < 20; ++i )
v4 += *(&String + i);
if ( v4 > 0 && v4 < 4132 )
{
v1 = malloc(v4);
sub_401020();
j___free_base(v1);
}
return MessageBoxA(0, Text, Caption, 0);
}
然而sub_401020()函数又是一个空函数,带着这个问题,我们继续分析TLS后面的内容。
int __cdecl sub_401040(HWND hDlg)
{
void *v1; // ST08_4
signed int i; // [esp+Ch] [ebp-24h]
signed int v4; // [esp+10h] [ebp-20h]
CHAR String; // [esp+18h] [ebp-18h]
int v6; // [esp+19h] [ebp-17h]
int v7; // [esp+1Dh] [ebp-13h]
int v8; // [esp+21h] [ebp-Fh]
int v9; // [esp+25h] [ebp-Bh]
__int16 v10; // [esp+29h] [ebp-7h]
char v11; // [esp+2Bh] [ebp-5h]
strcpy(Text, "try again!"); // //看到了,我们验证失败时候的字串
strcpy(Caption, "fail");
String = 0;
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
v10 = 0;
v11 = 0;
GetDlgItemTextA(hDlg, 1001, &String, 20);
v4 = 0;
for ( i = 0; i < 20; ++i )
v4 += *(&String + i);
if ( v4 > 0 && v4 < 4132 )
{
v1 = malloc(v4);
sub_401020();
j___free_base(v1);
}
return MessageBoxA(0, Text, Caption, 0);
}
然而sub_401020()函数又是一个空函数,带着这个问题,我们继续分析TLS后面的内容。
int sub_401C10()
{
void *v0; // edx
signed int j; // [esp+0h] [ebp-Ch]
signed int i; // [esp+8h] [ebp-4h]
sub_4018D0();
lpAddress = v0;
sub_4019B0(v0);
for ( i = 0; i < 5; ++i )
byte_4147DC[i] = *((_BYTE *)lpAddress + i + 32);
*(_DWORD *)&byte_414028[1] = (char *)sub_401A10 - (char *)((_BYTE *)lpAddress + 32) - 5;
for ( j = 0; j < 5; ++j )
*((_BYTE *)lpAddress + j + 32) = byte_414028[j];
return sub_4019E0(lpAddress);
}
这个函数看着和上一个函数很像,关键是v0(edx)指向的是什么地址呢?v0中的值看上去应该是 sub_4018D0()初始化的。先来看看这个函数。
int sub_401C10()
{
void *v0; // edx
signed int j; // [esp+0h] [ebp-Ch]
signed int i; // [esp+8h] [ebp-4h]
sub_4018D0();
lpAddress = v0;
sub_4019B0(v0);
for ( i = 0; i < 5; ++i )
byte_4147DC[i] = *((_BYTE *)lpAddress + i + 32);
*(_DWORD *)&byte_414028[1] = (char *)sub_401A10 - (char *)((_BYTE *)lpAddress + 32) - 5;
for ( j = 0; j < 5; ++j )
*((_BYTE *)lpAddress + j + 32) = byte_414028[j];
return sub_4019E0(lpAddress);
}
这个函数看着和上一个函数很像,关键是v0(edx)指向的是什么地址呢?v0中的值看上去应该是 sub_4018D0()初始化的。先来看看这个函数。
分析这个函数之前我们先来温习点功课:FS段寄存器,TEB结构,PEB结构
1)FS段寄存器指向当前的TEB结构,在TEB编译0x30处是PEB指针,通过这个指针即可获得PED的地址。
2)
TEB和PEB的结构如下:
typedef struct _NT_TIB
{ // Size: 01C
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 000
PVOID StackBase; // 004
PVOID StackLimit; // 008
PVOID SubSystemTib; // 00C
union // 010
{
PVOID FiberData;
ULONG Version;
};
PVOID ArbitraryUserPointer; // 014
struct _NT_TIB *Self; // 018
} NT_TIB, *PNT_TIB;
typedef struct _TEB
{ // Size: FBC
NT_TIB Tib; // 000
PVOID EnvironmentPointer; // 01C
CLIENT_ID Cid; // 020
PVOID ActiveRpcHandle; // 028
PVOID ThreadLocalStoragePointer; // 02C
struct _PEB *ProcessEnvironmentBlock; // 030
ULONG LastErrorValue; // 034
ULONG CountOfOwnedCriticalSections; // 038
PVOID CsrClientThread; // 03C
struct _W32THREAD* Win32ThreadInfo; // 040
ULONG User32Reserved[0x1A]; // 044
ULONG UserReserved[5]; // 0AC
PVOID WOW32Reserved; // 0C0
LCID CurrentLocale; // 0C4
ULONG FpSoftwareStatusRegister; // 0C8
PVOID SystemReserved1[0x36]; // 0CC
LONG ExceptionCode; // 1A4
struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; // 1A8
UCHAR SpareBytes1[0x28]; // 1AC
GDI_TEB_BATCH GdiTebBatch; // 1D4
CLIENT_ID RealClientId; // 6B4
PVOID GdiCachedProcessHandle; // 6BC
ULONG GdiClientPID; // 6C0
ULONG GdiClientTID; // 6C4
PVOID GdiThreadLocalInfo; // 6C8
ULONG Win32ClientInfo[62]; // 6CC
PVOID glDispatchTable[0xE9]; // 7C4
ULONG glReserved1[0x1D]; // B68
PVOID glReserved2; // BDC
PVOID glSectionInfo; // BE0
PVOID glSection; // BE4
PVOID glTable; // BE8
PVOID glCurrentRC; // BEC
PVOID glContext; // BF0
NTSTATUS LastStatusValue; // BF4
UNICODE_STRING StaticUnicodeString; // BF8
WCHAR StaticUnicodeBuffer[0x105]; // C00
PVOID DeallocationStack; // E0C
PVOID TlsSlots[0x40]; // E10
LIST_ENTRY TlsLinks; // F10
PVOID Vdm; // F18
PVOID ReservedForNtRpc; // F1C
PVOID DbgSsReserved[0x2]; // F20
ULONG HardErrorDisabled; // F28
PVOID Instrumentation[14]; // F2C
PVOID SubProcessTag; // F64
PVOID EtwTraceData; // F68
PVOID WinSockData; // F6C
ULONG GdiBatchCount; // F70
BOOLEAN InDbgPrint; // F74
BOOLEAN FreeStackOnTermination; // F75
BOOLEAN HasFiberData; // F76
UCHAR IdealProcessor; // F77
ULONG GuaranteedStackBytes; // F78
PVOID ReservedForPerf; // F7C
PVOID ReservedForOle; // F80
ULONG WaitingOnLoaderLock; // F84
ULONG SparePointer1; // F88
ULONG SoftPatchPtr1; // F8C
ULONG SoftPatchPtr2; // F90
PVOID *TlsExpansionSlots; // F94
ULONG ImpersionationLocale; // F98
ULONG IsImpersonating; // F9C
PVOID NlsCache; // FA0
PVOID pShimData; // FA4
ULONG HeapVirualAffinity; // FA8
PVOID CurrentTransactionHandle; // FAC
PTEB_ACTIVE_FRAME ActiveFrame; // FB0
PVOID FlsData; // FB4
UCHAR SafeThunkCall; // FB8
UCHAR BooleanSpare[3]; // FB9
} TEB, *PTEB;
typedef struct _LIST_ENTRY
{ // Size: 008
struct _LIST_ENTRY *Flink; // 000 从前到后
struct _LIST_ENTRY *Blink; // 004 从后到前
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _PER_LDR_DATA
{ // Size: 0024
ULONG Length; // 000
BOOLEAN Initialize; // 004
PVOID SsHandle; // 008
LIST_ENTRY InLoadOrderModuleList; // 00C
LIST_ENTRY InMemoryOrderModuleList; // 014
LIST_ENTRY InInitializationOrderModuleList; // 01C
} PER_LDR_DATA, *PPER_LDR_DATA;
typedef struct _UNICODE_STRING
{ // Size: 008
USHORT Length; // 000 占用的内存字节数,个数*2;
USHORT MaximumLength; // 002
PWSTR Buffer; // 004
} UNICODE_STRING ,*PUNICODE_STRING;
typedef struct _LDR_DATA_TABLE_ENTRY
{ // Size: 050
LIST_ENTRY InLoadOrderLinks; // 000 LIST_ENTRY里的Flink和Blink其实是指向LDR_MODULE结构,即LDR_DATA_TABLE_ENTRY
LIST_ENTRY InMemoryOrderLinks; // 008 同上
LIST_ENTRY InInitializationOrderLinks; // 010 同上
PVOID DllBase; // 018
PVOID EntryPoint; // 01C
ULONG SizeOfImage; // 020
UNICODE_STRING FullDllName; // 024
UNICODE_STRING BaseDllName; // 02C
ULONG Flags; // 034
WORD LoadCount; // 038
WORD TlsIndex; // 03A
union // 03C
{
LIST_ENTRY HashLinks; // 03C
struct
{
PVOID SectionPointer; // 03C
ULONG CheckSum; // 040
};
};
union
{
ULONG TimeDateStamp; // 044
PVOID LoadedImports; // 044
};
_ACTIVATION_CONTEXT * EntryPointActivationContext; // 048
PVOID PatchInformation; // 04C
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB
{ // Size: 1D8
UCHAR InheritedAddressSpace; // 000
UCHAR ReadImageFileExecOptions; // 001
UCHAR BeingDebugged; // 002
UCHAR SpareBool; // 003 Allocation size
HANDLE Mutant; // 004
HINSTANCE ImageBaseAddress; // 008
struct _PER_LDR_DATA *Ldr; // 00C
strcut _RTL_USER_PPROCESS_PARAMETERS *ProcessParameters; // 010
ULONG SubSystemData; // 014
HANDLE DefaultHeap; // 018
KSPIN_LOCK FastPebLock; // 01C
ULONG FastPebLockRoutine; // 020
ULONG FastPebUnlockRoutine; // 024
ULONG EnvironmentUpdateCount; // 028
ULONG KernelCallbackTable; // 02C
LARGE_INTEGER SystemReserved; // 030
struct _PER_FREE_BLOCK *FreeList; // 038
ULONG TlsExpansionCounter; // 03C
ULONG TlsBitmap; // 040
LARGE_INTEGER TlsBitmapBits; // 044
ULONG ReadOnlySharedMemoryBase; // 04C
ULONG ReadOnlySharedMemoryHeap; // 050
ULONG ReadOnlyStaticServerData; // 054
ULONG AnsiCodePageData; // 058
ULONG OemCodePageData; // 05C
ULONG UnicodeCaseTableData; // 060
ULONG NumberOfProcessors; // 064
LARGE_INTEGER NtGlobalFlag; // 068 Address of a local copy
LARGE_INTEGER CriticalSectionTimeout; // 070
ULONG HeapSegmentReserve; // 078
ULONG HeapSegmentCommit; // 07C
ULONG HeapDeCommitTotalFreeThreshold; // 080
ULONG HeapDeCommitFreeBlockThreshold; // 084
ULONG NumberOfHeaps; // 088
ULONG MaximumNumberOfHeaps; // 08C
ULONG ProcessHeaps; // 090
ULONG GdiSharedHandleTable; // 094
ULONG ProcessStarterHelper; // 098
ULONG GdiDCAttributeList; // 09C
KSPIN_LOCK LoaderLock; // 0A0
ULONG OSMajorVersion; // 0A4
ULONG OSMinorVersion; // 0A8
USHORT OSBuildNumber; // 0AC
USHORT OSCSDVersion; // 0AE
ULONG OSPlatformId; // 0B0
ULONG ImageSubsystem; // 0B4
ULONG ImageSubsystemMajorVersion; // 0B8
ULONG ImageSubsystemMinorVersion; // 0BC
ULONG ImageProcessAffinityMask; // 0C0
ULONG GdiHandleBuffer[0x22]; // 0C4
ULONG PostProcessInitRoutine; // 14C
ULONG TlsExpansionBitmap; // 150
UCHAR TlsExpansionBitmapBits[0x80]; // 154
ULONG SessionId; // 1D4
} PEB, *PPEB;
好了有了TEB,PEB数据结构的支撑,我们来分析
sub_4018D0()函数
typedef struct _NT_TIB
{ // Size: 01C
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 000
PVOID StackBase; // 004
PVOID StackLimit; // 008
PVOID SubSystemTib; // 00C
union // 010
{
PVOID FiberData;
ULONG Version;
};
PVOID ArbitraryUserPointer; // 014
struct _NT_TIB *Self; // 018
} NT_TIB, *PNT_TIB;
typedef struct _TEB
{ // Size: FBC
NT_TIB Tib; // 000
PVOID EnvironmentPointer; // 01C
CLIENT_ID Cid; // 020
PVOID ActiveRpcHandle; // 028
PVOID ThreadLocalStoragePointer; // 02C
struct _PEB *ProcessEnvironmentBlock; // 030
ULONG LastErrorValue; // 034
ULONG CountOfOwnedCriticalSections; // 038
PVOID CsrClientThread; // 03C
struct _W32THREAD* Win32ThreadInfo; // 040
ULONG User32Reserved[0x1A]; // 044
ULONG UserReserved[5]; // 0AC
PVOID WOW32Reserved; // 0C0
LCID CurrentLocale; // 0C4
ULONG FpSoftwareStatusRegister; // 0C8
PVOID SystemReserved1[0x36]; // 0CC
LONG ExceptionCode; // 1A4
struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; // 1A8
UCHAR SpareBytes1[0x28]; // 1AC
GDI_TEB_BATCH GdiTebBatch; // 1D4
CLIENT_ID RealClientId; // 6B4
PVOID GdiCachedProcessHandle; // 6BC
ULONG GdiClientPID; // 6C0
ULONG GdiClientTID; // 6C4
PVOID GdiThreadLocalInfo; // 6C8
ULONG Win32ClientInfo[62]; // 6CC
PVOID glDispatchTable[0xE9]; // 7C4
ULONG glReserved1[0x1D]; // B68
PVOID glReserved2; // BDC
PVOID glSectionInfo; // BE0
PVOID glSection; // BE4
PVOID glTable; // BE8
PVOID glCurrentRC; // BEC
PVOID glContext; // BF0
NTSTATUS LastStatusValue; // BF4
UNICODE_STRING StaticUnicodeString; // BF8
WCHAR StaticUnicodeBuffer[0x105]; // C00
PVOID DeallocationStack; // E0C
PVOID TlsSlots[0x40]; // E10
LIST_ENTRY TlsLinks; // F10
PVOID Vdm; // F18
PVOID ReservedForNtRpc; // F1C
PVOID DbgSsReserved[0x2]; // F20
ULONG HardErrorDisabled; // F28
PVOID Instrumentation[14]; // F2C
PVOID SubProcessTag; // F64
PVOID EtwTraceData; // F68
PVOID WinSockData; // F6C
ULONG GdiBatchCount; // F70
BOOLEAN InDbgPrint; // F74
BOOLEAN FreeStackOnTermination; // F75
BOOLEAN HasFiberData; // F76
UCHAR IdealProcessor; // F77
ULONG GuaranteedStackBytes; // F78
PVOID ReservedForPerf; // F7C
PVOID ReservedForOle; // F80
ULONG WaitingOnLoaderLock; // F84
ULONG SparePointer1; // F88
ULONG SoftPatchPtr1; // F8C
ULONG SoftPatchPtr2; // F90
PVOID *TlsExpansionSlots; // F94
ULONG ImpersionationLocale; // F98
ULONG IsImpersonating; // F9C
PVOID NlsCache; // FA0
PVOID pShimData; // FA4
ULONG HeapVirualAffinity; // FA8
PVOID CurrentTransactionHandle; // FAC
PTEB_ACTIVE_FRAME ActiveFrame; // FB0
PVOID FlsData; // FB4
UCHAR SafeThunkCall; // FB8
UCHAR BooleanSpare[3]; // FB9
} TEB, *PTEB;
typedef struct _LIST_ENTRY
{ // Size: 008
struct _LIST_ENTRY *Flink; // 000 从前到后
struct _LIST_ENTRY *Blink; // 004 从后到前
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _PER_LDR_DATA
{ // Size: 0024
ULONG Length; // 000
BOOLEAN Initialize; // 004
PVOID SsHandle; // 008
LIST_ENTRY InLoadOrderModuleList; // 00C
LIST_ENTRY InMemoryOrderModuleList; // 014
LIST_ENTRY InInitializationOrderModuleList; // 01C
} PER_LDR_DATA, *PPER_LDR_DATA;
typedef struct _UNICODE_STRING
{ // Size: 008
USHORT Length; // 000 占用的内存字节数,个数*2;
USHORT MaximumLength; // 002
PWSTR Buffer; // 004
} UNICODE_STRING ,*PUNICODE_STRING;
typedef struct _LDR_DATA_TABLE_ENTRY
{ // Size: 050
LIST_ENTRY InLoadOrderLinks; // 000 LIST_ENTRY里的Flink和Blink其实是指向LDR_MODULE结构,即LDR_DATA_TABLE_ENTRY
LIST_ENTRY InMemoryOrderLinks; // 008 同上
LIST_ENTRY InInitializationOrderLinks; // 010 同上
PVOID DllBase; // 018
PVOID EntryPoint; // 01C
ULONG SizeOfImage; // 020
UNICODE_STRING FullDllName; // 024
UNICODE_STRING BaseDllName; // 02C
ULONG Flags; // 034
WORD LoadCount; // 038
WORD TlsIndex; // 03A
union // 03C
{
LIST_ENTRY HashLinks; // 03C
struct
{
PVOID SectionPointer; // 03C
ULONG CheckSum; // 040
};
};
union
{
ULONG TimeDateStamp; // 044
PVOID LoadedImports; // 044
};
_ACTIVATION_CONTEXT * EntryPointActivationContext; // 048
PVOID PatchInformation; // 04C
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB
{ // Size: 1D8
UCHAR InheritedAddressSpace; // 000
UCHAR ReadImageFileExecOptions; // 001
UCHAR BeingDebugged; // 002
UCHAR SpareBool; // 003 Allocation size
HANDLE Mutant; // 004
HINSTANCE ImageBaseAddress; // 008
struct _PER_LDR_DATA *Ldr; // 00C
strcut _RTL_USER_PPROCESS_PARAMETERS *ProcessParameters; // 010
ULONG SubSystemData; // 014
HANDLE DefaultHeap; // 018
KSPIN_LOCK FastPebLock; // 01C
ULONG FastPebLockRoutine; // 020
ULONG FastPebUnlockRoutine; // 024
ULONG EnvironmentUpdateCount; // 028
ULONG KernelCallbackTable; // 02C
LARGE_INTEGER SystemReserved; // 030
struct _PER_FREE_BLOCK *FreeList; // 038
ULONG TlsExpansionCounter; // 03C
ULONG TlsBitmap; // 040
LARGE_INTEGER TlsBitmapBits; // 044
ULONG ReadOnlySharedMemoryBase; // 04C
ULONG ReadOnlySharedMemoryHeap; // 050
ULONG ReadOnlyStaticServerData; // 054
ULONG AnsiCodePageData; // 058
ULONG OemCodePageData; // 05C
ULONG UnicodeCaseTableData; // 060
ULONG NumberOfProcessors; // 064
LARGE_INTEGER NtGlobalFlag; // 068 Address of a local copy
LARGE_INTEGER CriticalSectionTimeout; // 070
ULONG HeapSegmentReserve; // 078
ULONG HeapSegmentCommit; // 07C
ULONG HeapDeCommitTotalFreeThreshold; // 080
ULONG HeapDeCommitFreeBlockThreshold; // 084
ULONG NumberOfHeaps; // 088
ULONG MaximumNumberOfHeaps; // 08C
ULONG ProcessHeaps; // 090
ULONG GdiSharedHandleTable; // 094
ULONG ProcessStarterHelper; // 098
ULONG GdiDCAttributeList; // 09C
KSPIN_LOCK LoaderLock; // 0A0
ULONG OSMajorVersion; // 0A4
ULONG OSMinorVersion; // 0A8
USHORT OSBuildNumber; // 0AC
USHORT OSCSDVersion; // 0AE
ULONG OSPlatformId; // 0B0
ULONG ImageSubsystem; // 0B4
ULONG ImageSubsystemMajorVersion; // 0B8
ULONG ImageSubsystemMinorVersion; // 0BC
ULONG ImageProcessAffinityMask; // 0C0
ULONG GdiHandleBuffer[0x22]; // 0C4
ULONG PostProcessInitRoutine; // 14C
ULONG TlsExpansionBitmap; // 150
UCHAR TlsExpansionBitmapBits[0x80]; // 154
ULONG SessionId; // 1D4
} PEB, *PPEB;
好了有了TEB,PEB数据结构的支撑,我们来分析
sub_4018D0()函数
int sub_4018D0()
{
int v0; // edx
sub_4018F5(0x3BD696F4);
return sub_401928(v0, 0x925DF53F);
}
0x3BD696F4是目标字串hash值,继续分析 sub_4018F5()
int sub_4018D0()
{
int v0; // edx
sub_4018F5(0x3BD696F4);
return sub_401928(v0, 0x925DF53F);
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2018-12-13 11:59
被ODPan编辑
,原因: