任务:找到windbg pdb符号对应文件夹名长串编码含义?
解决方法是用windbg调试windbg,下断点:
bp kernelbase!CreateFileA "da poi(esp+4);k;gc"
bp kernelbase!CreateFileW "du poi(esp+4);k;gc"
得到如下记录:
0938e15c "d:\symbol\cmd.pdb\A609EC1CBCFF43"
0938e19c "43AEFC312495558D832\cmd.pdb"
ChildEBP RetAddr
04d6a670 70af02cb KERNELBASE!CreateFileW
04d6a6ac 70af1a7e dbghelp!IStreamCRTFile::Create+0x8b
04d6a6d4 70af08c5 dbghelp!MSF_HB::internalOpen+0x2e
04d6a6f0 70ae8d47 dbghelp!MSF::Open+0x35
04d6a724 70ae90df dbghelp!PDB1::OpenEx2W+0xc7
04d6a74c 70af335f dbghelp!PDB::OpenEx2W+0x1f
04d6a770 70a91294 dbghelp!PDBCommon::Open2W+0x1f
04d6a794 70a3af14 dbghelp!CDiaDataSource::loadDataFromPdb+0x44
04d6abf8 70a56f4c dbghelp!diaGetPdb+0x1fc
04d6ae28 70a55bdd dbghelp!GetDebugData+0x230
04d6b2c8 70a55885 dbghelp!modload+0x285
04d6b2f4 70a4c177 dbghelp!LoadSymbols+0x355
04d6b328 70a4d44d dbghelp!ModLoop+0x86
04d6d2e4 70a50ef8 dbghelp!EnumSymbols+0xec
04d6d318 70d0fabf dbghelp!SymEnumSymbolsExW+0x59
04d6d480 70d0fbf7 dbgeng!EnumModuleTypedData+0xef
04d6e170 70d1024c dbgeng!EnumAllModuleTypedData+0xf4
04d6e3b8 70cca72b dbgeng!ParseExamine+0x504
04d6e428 70cca955 dbgeng!ProcessCommands+0x11c3
04d6e488 70c3cdd4 dbgeng!ProcessCommandsAndCatch+0x91
04d6e8f4 70c3cfc5 dbgeng!Execute+0x226
04d6e944 00dde653 dbgeng!DebugClient::ExecuteWide+0x8d
04d6ed08 00ddea93 windbg!ProcessCommand+0x145
04d6fd28 00de0275 windbg!ProcessEngineCommands+0xd1
04d6fd40 7567919f windbg!EngineLoop+0x390
04d6fd4c 77b0b5af KERNEL32!BaseThreadInitThunk+0xe
04d6fd94 77b0b57a ntdll!__RtlUserThreadStart+0x2f
04d6fda4 00000000 ntdll!_RtlUserThreadStart+0x1b
现在来被调试的windbg调试windows\syswow64\cmd.exe,由于有了pdb,分析过程变得极为容易,跟踪便可以知道modload中首次初始化路径cmd.pdb,而diaGetPdb中该地址最终变幻成d:\symbol\cmd.pdb\A609EC1CBCFF4343AEFC312495558D832\cmd.pdb
,现在就是要知道A609EC1CBCFF4343AEFC312495558D832从何而来,因此从diaGetPdb入手,跟踪后可以发现dbghelpb把内存中PE的PROCESS_ENTRY结构和文件名以及符号服务器等传给了symsrv.dll,symsrv!SymbolServerWEx完成返回完整路径的任务,这个任务包括:
- TestParameters函数检测传入参数合法性
- SymbolServerGetIndexStringW函数返回index,也就是这里的A609EC1CBCFF4343AEFC312495558D832
- SymbolServerByIndexW根据index返回pdb完整路径
- 解析出SymbolServerByIndexW的参数:WCHAR *srv, WCHAR *pdbname, BYTE *indexdata, int dword1, int dword2, WCHAR *outpath,PDWORD unknown
- 解析出SymbolServerGetIndexStringW的参数:WCHAR* srv,WCHAR* pdbname(无路径),BYTE* index ,int dword1,int dword2,WCHAR* formatted,int len,发现index经过变换后即是结果,如wntdll.pdb。
传入:8365a747 c534bc47 a03e6293 a78c675f
结果:47A76583 34C547BC A03E6293 A78C675F2
现有任务变为2个:
- 1.传入index源自何处?这需要向上层调用寻找
- 2.末尾2如何计算?这需要分析SymbolServerGetIndexStringW
解决问题
逐层向上标记参数,
symsrv_SymbolServerWEx —> CallSymbolServerGetFile -> symsrvGetFile -> HandleLocatePdbInSymSrvOrLocalStore
到这一层后发现参数只有类指针this,我们需要关注symsrvGetFile的对应参数indexdata,param1,param2,indexdata位于this+27780处,dword1为*(DWORD*)(this+24624),dword2为0,需要了解这些位置在什么地方进行了改动,在往上层进入了线程回调函数 GetPdbThreadProc,这里需要看看哪里调用的线程,并找到传递的参数之前在哪里改变的,到了DiaLocatePdbMultiThread,伪代码:
v17 = *(this + 4052);
if ( *(v17 + 4) != 3 || *(v17 + 12) != 20 )
{
dword1__________ = param6;//GUID*
v18 = param4;
}
else
{
v18 = *(v17 + 8);
dword1__________ = *(v18 + 4);
}
if ( param5 )//GUID*
{
indexdata = param5;
}
else if ( v18 )
{
indexdata = *v18;//param+2180
}
再向上层看,diaGetPdb中
param4=this+2180 param5=*(this+2172) param6=*(this+2168)
RetrievePdbInfo
this+2180 => thisb+4
this+2172 => 0
this+2168 => thisb+20
thisb=*(DWORD*)(this+3252)
需要知道this+3252何时写入:
int __fastcall ReadHeader(int thisc, unsigned __int32 a2)
{
unsigned __int32 v2; // ebx@1
int v3; // esi@1
QWORD v5; // rax@5
struct _IMGHLP_DEBUG_DATA *pebegin2; // edi@5
DWORD filesize; // eax@5
BYTE *v8; // eax@6
void *v9; // eax@7
void *v10; // ecx@7
unsigned __int64 v11; // ST10_8@9
unsigned __int64 v12; // ST10_8@13
__int16 v13; // cx@14
LPVOID v14; // eax@21
int v15; // edi@21
int v16; // ecx@22
int v17; // edx@24
int v18; // eax@24
char v19; // di@24
int v20; // ecx@27
unsigned __int64 v21; // ST10_8@31
struct _IMGHLP_DEBUG_DATA *v22; // edx@37
unsigned __int64 v23; // ST10_8@42
unsigned __int64 v24; // ST10_8@43
signed int PESIG; // edx@44
int v26; // eax@45
LPVOID v27; // ecx@45
unsigned __int64 v28; // ST10_8@47
unsigned __int64 v29; // ST10_8@50
unsigned __int64 v30; // ST10_8@61
int imagesize; // eax@65
void *v32; // eax@74
LPVOID sectiondata; // eax@74
int v34; // ecx@75
BYTE *v35; // ecx@76
int v36; // ecx@76
const void *secheader; // eax@76
unsigned __int32 v38; // edx@83
unsigned __int64 v39; // ST10_8@84
unsigned __int32 v40; // eax@85
unsigned __int64 v41; // ST10_8@88
LPVOID v42; // eax@98
int v43; // edx@116
unsigned __int32 v44; // [sp-4h] [bp-3A4h]@116
void *v45; // [sp+0h] [bp-3A0h]@0
void *v46; // [sp+0h] [bp-3A0h]@9
unsigned __int32 v47; // [sp+0h] [bp-3A0h]@13
void *v48; // [sp+0h] [bp-3A0h]@42
unsigned __int32 v49; // [sp+0h] [bp-3A0h]@43
void *v50; // [sp+0h] [bp-3A0h]@83
struct _IMAGE_SECTION_HEADER *v51; // [sp+0h] [bp-3A0h]@85
unsigned int v52; // [sp+4h] [bp-39Ch]@0
unsigned int v53; // [sp+4h] [bp-39Ch]@9
unsigned __int32 v54; // [sp+4h] [bp-39Ch]@13
unsigned int v55; // [sp+4h] [bp-39Ch]@42
unsigned __int32 v56; // [sp+4h] [bp-39Ch]@43
unsigned int v57; // [sp+4h] [bp-39Ch]@83
struct _IMAGE_DATA_DIRECTORY *v58; // [sp+4h] [bp-39Ch]@85
int v59; // [sp+14h] [bp-38Ch]@76
int filesize2; // [sp+24h] [bp-37Ch]@74
unsigned __int32 filesize2a; // [sp+24h] [bp-37Ch]@87
DWORD filesize2_4; // [sp+28h] [bp-378h]@7
BYTE *exportpos; // [sp+2Ch] [bp-374h]@1
unsigned __int64 v64; // [sp+30h] [bp-370h]@1
int v65; // [sp+38h] [bp-368h]@9
BYTE *v66; // [sp+3Ch] [bp-364h]@1
unsigned int v67; // [sp+40h] [bp-360h]@1
void *sectiondata_1; // [sp+44h] [bp-35Ch]@21
LPVOID lpMem; // [sp+48h] [bp-358h]@1
void *v70; // [sp+4Ch] [bp-354h]@5
int v71; // [sp+50h] [bp-350h]@5
struct _IMGHLP_DEBUG_DATA *pebegin; // [sp+54h] [bp-34Ch]@5
BYTE v73[28]; // [sp+58h] [bp-348h]@31
BYTE v74[264]; // [sp+74h] [bp-32Ch]@61
unsigned __int64 v75; // [sp+17Ch] [bp-224h]@88
char v76; // [sp+18Ch] [bp-214h]@89
int v77; // [sp+1C0h] [bp-1E0h]@88
BYTE v78[248]; // [sp+1C4h] [bp-1DCh]@1
unsigned __int16 v79[40]; // [sp+2BCh] [bp-E4h]@50
BYTE Dst[64]; // [sp+30Ch] [bp-94h]@1
unsigned __int64 v81; // [sp+350h] [bp-50h]@13
int v82; // [sp+358h] [bp-48h]@17
int v83; // [sp+35Ch] [bp-44h]@17
int v84; // [sp+360h] [bp-40h]@18
int v85; // [sp+364h] [bp-3Ch]@20
void *v86; // [sp+368h] [bp-38h]@21
int v87; // [sp+36Ch] [bp-34h]@24
unsigned int v88; // [sp+370h] [bp-30h]@23
int v89; // [sp+374h] [bp-2Ch]@17
CPPEH_RECORD ms_exc; // [sp+388h] [bp-18h]@9
v2 = a2;
v3 = thisc;
*Dst = 0;
memset(&Dst[2], 0, 0x3Eu);
*v78 = 0;
memset(&v78[4], 0, 0xF4u);
lpMem = 0;
v66 = 0;
HIDWORD(v64) = 0;
exportpos = 0;
v67 = 0;
if ( v2 == 1 )
{
v9 = *(v3 + 3412);
v71 = *(v3 + 3412);
pebegin2 = *(v3 + 16);
pebegin = *(v3 + 16);
v10 = *(v3 + 20);
v70 = *(v3 + 20);
filesize2_4 = 0;
*(v3 + 3248) = 5;
}
else
{
if ( v2 == 2 )
{
v71 = 0;
v8 = MapItRO(*(v3 + 1096), 0);
*(v3 + 1104) = v8;
pebegin2 = v8;
v70 = (v8 >> 32);
pebegin = v8;
filesize = GetFileSize(*(v3 + 1096), 0);
*(v3 + 3248) = 2;
}
else
{
if ( v2 != 3 )
return 0;
v71 = 0;
LODWORD(v5) = MapItRO(*(v3 + 2156), 0);
*(v3 + 2160) = v5;
pebegin2 = v5;
v70 = (v5 >> 32);
pebegin = v5;
filesize = GetFileSize(*(v3 + 2156), 0);
*(v3 + 3248) = 3;
}
filesize2_4 = filesize;
v9 = v71;
v10 = v70;
}
*(v3 + 4024) = 0;
v65 = 0;
ms_exc.registration.TryLevel = 0;
HIDWORD(v11) = 2;
LODWORD(v11) = &v64;
if ( !ReadImageData(v9, pebegin2, v10, 0i64, v11, v45, v52) )// 读取2个字节
goto LABEL_10;
*(v3 + 3240) = v2;
if ( v64 != 'ID' )
{
if ( v64 == 'ZM' ) // 如果是MZ头
{
HIDWORD(v23) = 64;
LODWORD(v23) = Dst;
if ( !ReadImageData(v71, pebegin2, v70, 0i64, v23, v46, v53) )// 读取64字节以取得PE头所在位置
goto LABEL_10;
HIDWORD(v24) = 248;
LODWORD(v24) = v78;
if ( !ReadImageData(v71, pebegin2, v70, *&Dst[60], v24, v48, v55) )// 读取248字节到v93
goto LABEL_10;
PESIG = *v78;
if ( *v78 != 'EP' ) // 如果是PE头
{
v66 = &v78[4];
v26 = *&v78[20] + 24 + *&Dst[60];
v27 = &v78[24];
LABEL_55:
HIDWORD(v64) = v26;
goto LABEL_56;
}
}
else
{
if ( v64 != 0x14C )
{
HIDWORD(v29) = 76;
LODWORD(v29) = v79;
if ( !ReadImageData(v71, pebegin2, v70, 0i64, v29, v46, v53) )
goto LABEL_10;
if ( v79[0] != 332 && v79[0] != 388 && v79[0] != 644 )
goto LABEL_11;
v27 = &v79[10];
v66 = v79;
v26 = v79[8] + 20;
PESIG = *v78;
goto LABEL_55;
}
HIDWORD(v28) = 244;
LODWORD(v28) = &v78[4];
if ( !ReadImageData(v71, pebegin2, v70, 0i64, v28, v46, v53) )
goto LABEL_11;
PESIG = 'ROM ';
*v78 = 'ROM ';
}
v27 = lpMem;
LABEL_56:
if ( v27 )
{
if ( *v27 != 0x107 )
{
*(v3 + 4592) = 11;
goto LABEL_11;
}
v19 = 1;
*(v3 + 3400) = 1;
*(v3 + 1108) = *v27;
*(v3 + 24) = *(v27 + 5);
*(v3 + 28) = 0;
*(v3 + 32) = *(v27 + 1);
*(v3 + 36) = 0;
goto LABEL_74;
}
if ( *&v78[24] != 0x20B ) // IMAGE_OPTIONAL_HEADER32.MAGIC=PE64
{
v66 = &v78[4];
exportpos = &v78[120]; // 导出表位置
*(v3 + 1108) = *&v78[24];
if ( PESIG == 'ROM ' )
HIDWORD(v64) = 244;
else
HIDWORD(v64) = *&Dst[60] + 248; // 第一个节位置
v19 = 1;
if ( v2 == 2 || v2 == 1 )
{
*(v3 + 24) = *&v78[52];
*(v3 + 28) = 0;
*(v3 + 3392) = *&v78[56];
*(v3 + 36) = *&v78[88];
}
imagesize = *&v78[80];
goto LABEL_73;
}
HIDWORD(v30) = 264;
LODWORD(v30) = v74;
if ( ReadImageData(v71, pebegin2, v70, *&Dst[60], v30, v49, v56) )
{
v66 = &v74[4];
exportpos = &v74[136];
HIDWORD(v64) = *&Dst[60] + 264;
*(v3 + 1108) = *&v74[24];
v19 = 1;
*(v3 + 3396) = 1;
if ( v2 == 2 || v2 == 1 )
{
*(v3 + 24) = *&v74[48];
*(v3 + 28) = *&v74[52];
*(v3 + 3392) = *&v74[56];
*(v3 + 36) = *&v74[88];
}
imagesize = *&v74[80];
LABEL_73:
*(v3 + 32) = imagesize;
LABEL_74:
imgset(100, *(v3 + 4036), v2, v2, v49, v56);
v32 = *(v66 + 1); // 得到节个数
lpMem = v32;
filesize2 = 40 * v32;
sectiondata = pMemAlloc(40 * v32);
sectiondata_1 = sectiondata;
if ( sectiondata && ReadImageData(v71, pebegin, v70, HIDWORD(v64), __PAIR__(filesize2, sectiondata), v47, v54) )// 读取所有节数据
{
ImageHelpPointerWrapper<_IMAGE_SECTION_HEADER>::Assign((v3 + 3352), sectiondata_1, lpMem, v34);
*(v3 + 3340) = sectiondata_1;
*(v3 + 3380) = lpMem;
v35 = v66;
*(v3 + 48) = *v66;
*(v3 + 40) = *(v35 + 1);
*(v3 + 44) = *(v35 + 9);
imgset(101, *(v3 + 4036), v2, v2, v47, v54);
v36 = 0;
v59 = 0;
secheader = sectiondata_1;
while ( v36 < lpMem )
{
if ( *(v3 + 3400) && !(*(v66 + 9) & 0x200) )
{
if ( !memcmp(secheader, ".rdata", 7u) )// 遇到.rdata不再读取节信息
{
v20 = 1;
v67 = 1;
v18 = *(sectiondata_1 + 3);
v65 = *(sectiondata_1 + 3);
goto LABEL_28;
}
secheader = sectiondata_1;
}
v38 = SectionContains(secheader, v71, exportpos, v47, v54);// 计算导出表在文件中的位置
if ( v38 )
{
*(v3 + 3944) = v2;
*(v3 + 4048) = *(exportpos + 1);
*(v3 + 4040) = *exportpos;
*(v3 + 4044) = 0;
HIDWORD(v39) = 40;
LODWORD(v39) = v3 + 3984;
ReadImageData(v71, pebegin, v70, v38, v39, v50, v57);// 读40字节
}
v40 = SectionContains(sectiondata_1, v71, exportpos + 12, v50, v57);// 计算调试信息在文件中的位置
if ( v40 )
{
v65 = v40; // v65=调试信息偏移
v67 = *(exportpos + 13) / 28u; // 调试信息个数
}
filesize2a = SectionContains(sectiondata_1, v71, exportpos + 28, v51, v58);// 计算CLR信息在文件中的位置
if ( filesize2a )
{
memset(&v75, 0, 0x48u);
HIDWORD(v41) = 72;
LODWORD(v41) = &v75;
ReadImageData(v71, pebegin, v70, filesize2a, v41, v47, v54);
if ( v77 || v76 & 1 )
*(v3 + 4648) = 1;
}
v36 = v59++ + 1;
secheader = sectiondata_1 + 40; // 取下一个section头
sectiondata_1 = sectiondata_1 + 40;
}
}
goto LABEL_26;
}
LABEL_10:
dword_6BC5FB1C = 6;
LABEL_11:
ms_exc.registration.TryLevel = -2;
return 0;
}
HIDWORD(v12) = 48;
LODWORD(v12) = &v81;
if ( !ReadImageData(v71, pebegin2, v70, 0i64, v12, v46, v53) )
goto LABEL_11;
v13 = WORD2(v81);
if ( WORD2(v81) != 332 && WORD2(v81) != 388 )
{
UnmapViewOfFile(*(v3 + 2160));
*(v3 + 2160) = 0;
goto LABEL_11;
}
*(v3 + 3392) = v89;
*(v3 + 36) = v83;
*(v3 + 48) = v13;
*(v3 + 40) = v82;
*(v3 + 44) = WORD3(v81);
if ( !*(v3 + 24) )
{
*(v3 + 24) = v84;
*(v3 + 28) = 0;
}
if ( !*(v3 + 32) )
*(v3 + 32) = v85;
lpMem = v86;
HIDWORD(v64) = 40 * v86;
v14 = pMemAlloc(40 * v86);
v15 = v14;
sectiondata_1 = v14;
if ( v14 )
{
if ( ReadImageData(v71, pebegin, v70, 0x30ui64, __PAIR__(HIDWORD(v64), v14), v47, v54) )
{
ImageHelpPointerWrapper<_IMAGE_SECTION_HEADER>::Assign((v3 + 3352), v15, lpMem, v16);
*(v3 + 3344) = v15;
*(v3 + 3384) = lpMem;
if ( v88 )
{
v67 = v88 / 0x1C;
v17 = 40 * v86 + 48;
v18 = v17 + v87;
v65 = v17 + v87;
v19 = 1;
goto LABEL_27;
}
}
}
v19 = 1;
LABEL_26:
v18 = v65;
LABEL_27:
v20 = v67;
LABEL_28:
if ( v2 == 2 )
{
*(v3 + 3364) = v18;
*(v3 + 3368) = v20;
}
while ( v20 )
{
HIDWORD(v21) = 28;
LODWORD(v21) = v73;
if ( !ReadImageData(v71, pebegin, v70, v18, v21, v47, v54) )// 逐个读取调试信息
goto LABEL_11;
if ( *&v73[16] ) // IMAGE_DEBUG_DIRECTORY.SizeOfData
{
imgset(*&v73[12], *(v3 + 4036), v2, 0, v47, v54);
if ( *&v73[12] == 1 )
{
if ( *&v73[24] < filesize2_4 )
{
ImageHelpPointerWrapper<_OMAP>::Assign((v3 + 3264), (pebegin + *&v73[24]), *&v73[16], v19);
*(v3 + 3948) = v2;
goto LABEL_95;
}
*(v3 + 4024) = 1;
}
else
{
if ( *&v73[12] == 2 )
{
if ( v71 )
{
if ( !*&v73[20] )
goto LABEL_11;
v42 = pMemAlloc(*&v73[16]);
lpMem = v42;
if ( !v42 )
goto LABEL_108;
if ( !ReadImageData(v71, pebegin, v70, *&v73[20], __PAIR__(*&v73[16], v42), v47, v54) )
{
pMemFree(lpMem);
goto LABEL_11;
}
ImageHelpPointerWrapper<_OMAP>::Assign((v3 + 0xCB4), lpMem, *&v73[16], 0);
}
else
{
if ( *&v73[24] >= filesize2_4 ) // IMAGE_OPTIONAL_HEADER.PointerToRawData 此处就是我们要的数据了
goto LABEL_108;
ImageHelpPointerWrapper<_OMAP>::Assign((v3 + 0xCB4), (pebegin + *&v73[24]), *&v73[16], 1);
}
*(v3 + 3952) = v2;
RetrievePdbInfo(v3, v3);
goto LABEL_95;
}
if ( *&v73[12] != 4 )
goto LABEL_108;
if ( *&v73[24] < filesize2_4 )
{
v22 = pebegin;
if ( *(pebegin + *&v73[24]) != 1 )
goto LABEL_109;
if ( v2 == 3 )
{
v22 = pebegin;
if ( !*(v3 + 572) )
{
ansi2wcs(0x105, v47, v54);
goto LABEL_108;
}
LABEL_109:
if ( *&v73[24] >= filesize2_4 )
goto LABEL_120;
if ( *&v73[12] != 3 )
{
if ( *&v73[12] == 5 )
{
*(v3 + 3972) = v2;
v44 = v2;
v43 = 5;
}
else
{
if ( *&v73[12] == 7 )
{
ImageHelpPointerWrapper<_OMAP>::Assign((v3 + 3316), (v22 + *&v73[24]), *&v73[16] >> 3, v19);
*(v3 + 3964) = v2;
}
else
{
if ( *&v73[12] != 8 )
goto LABEL_120;
ImageHelpPointerWrapper<_OMAP>::Assign((v3 + 3328), (v22 + *&v73[24]), *&v73[16] >> 3, v19);
*(v3 + 3968) = v2;
}
LABEL_118:
v44 = v2;
v43 = *&v73[12];
}
imgset(v43, *(v3 + 4036), 0, v44, v47, v54);
goto LABEL_120;
}
ImageHelpPointerWrapper<_OMAP>::Assign((v3 + 3280), (v22 + *&v73[24]), *&v73[16] >> 4, v19);
*(v3 + 3960) = v2;
goto LABEL_118;
}
if ( *(v66 + 9) & 0x200 )
{
ansi2wcs(0x105, v47, v54);
*(v3 + 2164) = *&v73[4];
}
else
{
ansi2wcs(0x105, v47, v54);
}
}
LABEL_95:
imgset(*&v73[12], *(v3 + 4036), 0, v2, v47, v54);
}
LABEL_108:
v22 = pebegin;
goto LABEL_109;
}
LABEL_120:
v18 = v65 + 28;
v65 += 28;
v20 = v67-- - 1;
}
return 1;
}
可以看到dbghelp!ReadHeader读取文件,解析PE格式,然后提取其中的debug区信息,标志RSDS后存放的GUID即为我们要找的数据
0293cbd4 52 53 44 53 83 65 a7 47-c5 34 bc 47 a0 3e 62 93 RSDS.e.G.4.G.>b.
0293cbe4 a7 8c 67 5f 02 00 00 00-77 6e 74 64 6c 6c 2e 70 ..g_....wntdll.p
0293cbf4 64 62 00 00 00 00 00 00-00 00 00 00 f6 c1 03 75 db.............u
0293cc04 0d 39 71 0c 75 08 8b 41-04 3b 46 08 74 4d 83 26 .9q.u..A.;F.tM.&
0293cc14 00 83 66 04 00 eb 42 90-90 90 90 90 8b ff 55 8b ..f...B.......U.
0293cc24 ec 51 53 8b 5d 08 57 8b-7d 0c 3b 7b 10 0f 87 02 .QS.].W.}.;{....
0293cc34 01 00 00 8b 43 0c 56 8d-73 20 3b c7 73 0e 83 c6 ....C.V.s ;.s...
0293cc44 10 03 c0 eb f5 90 90 90-90 90 90 90 8b ce e8 99 ................
解决任务2的重点在于SymbolServerGetIndexStringW,来看他的内部调用:
- CatStrID 将前面BYTE* index经过一定变换转换成字符串
- CatStrDWORD 将前面int dword1添加到字符串结尾
- CatStrDWORD 将前面int dword2添加到字符串结尾
CatStrID中实现大概是这样:
switch(gptype)
{
case 2:
CatStrDWORD(buf,id);
break;
case 4:
CatStrDWORD(buf,*(DWORD*)id);
break;
case 8:
CatStrGUID(buf,id);//我们用到的case
break;
case 0x10:
CatStrOldGUID(buf,id);
break;
case 0x400000:
wcscpy_s(buf,id);
}
CatStrDWORD中实现大概是这样:
if(dwordn)
{
sprintf(buf,"%s%d",index,dwordn);
}