终于搞清楚Manifest的解压问题了
2015年12月13日
19:47
Manifest的解压缩问题,今天终于搞清楚了。
1、它也是增量压缩;
2、源文件很特别,包含在 wcp.dll中,是固定的一段文本,可以称为模板。
以 Win10 x86版本为例,模板在0x0027bea0处,长度0x236a。
intReadManifestTemplate()
{
char temp[0x236a];
WCHAR* inFilename =L"C:\\ServicingStack-10\\x86\\wcp.dll";
ifstream fin(inFilename,ios::binary);
fin.seekg(0x0027bea0);
fin.read(temp, 0x236a);
WCHAR* filename =L"C:\\ServicingStack-10\\Manifest.template";
ofstream fout(filename, ios::binary);
fout.write(temp, 0x236a);
fout.close();
return 0;
}
为了方便使用,可以把这部分提取出来,单独保存为一个文件;
3、后面的解压缩就与正常的增量压缩一样了。
本来,wcp.dll 中就有 DecompressManifest 的函数,只是由于能力有限,调用函数的企图没有成功,在最后一步,释放内存时出错。
还要再努力。
可能是由于在调试模式下,系统会创建有关跟踪的类,而在发行模式下,就没有这样的类,我们的程序是在中途插入的,未能对有关跟踪的类进行必要的初始化,因此,在调试模式下,是会释放相关的内存空间,但是,却没有创建,故程序出错,而在发行模式下,不需要这样的跟踪类,故程序可以正常运行。
下面的程序可能是用于创建的函数:
void sub_1012A554()
{
int v0; // ecx@2
int v1; // eax@2
int v2; // edi@3
void (__thiscall *v3)(_DWORD, _DWORD); // esi@7
void (__thiscall *v4)(_DWORD, _DWORD); // esi@7
char v5; // [sp+Ch] [bp-14h]@13
PVOID DllImageBase; // [sp+10h] [bp-10h]@9
__int16 v7; // [sp+14h] [bp-Ch]@2
int v8; // [sp+18h] [bp-8h]@6
if ( !dword_1027D5A4 )
{
sub_1008FED7((int)&v7);
sub_1012A39C(&Name, v0);
v1 = (int)RtlAllocateHeap(*(HANDLE *)(__readfsdword(48) + 24), 0, 0x834u);
if ( v1 )
v2 = sub_1012A3B0(v1);
else
v2 = 0;
if ( !v2 )
goto LABEL_14;
sub_1012A490(v2, (PWSTR)(v7 != 0 ? v8 : 0));
if ( _InterlockedCompareExchange((volatile signed __int32 *)&dword_1027D5A4, v2, 0) )
{
v3 = *(void (__thiscall **)(_DWORD, _DWORD))(*(_DWORD *)v2 + 224);
__guard_check_icall_fptr(*(_DWORD *)(*(_DWORD *)v2 + 224));
v3(v2, 0);
v4 = *(void (__thiscall **)(_DWORD, _DWORD))(*(_DWORD *)v2 + 224);
__guard_check_icall_fptr(*(_DWORD *)(*(_DWORD *)v2 + 224));
v4(v2, 1);
}
if ( !ModuleImageBase )
{
DllImageBase = 0;
if ( LdrGetDllHandle(0, 0, &dword_10012D0C, &DllImageBase) < 0
|| LdrLoadDll(0, 0, &dword_10012D0C, &DllImageBase) < 0 )
goto LABEL_14;
if ( _InterlockedCompareExchange((volatile signed __int32 *)&ModuleImageBase, (signed __int32)DllImageBase, 0) )
LdrUnloadDll(DllImageBase);
}
_InterlockedOr((volatile signed __int32 *)&v5, 0);
LdrGetProcedureAddress(ModuleImageBase, &stru_10012D1C, 0, &ProcedureAddress);
LABEL_14:
sub_1008FF20(&v7);
}
}
是否如此,尚需验证。
可能也不是这个原因,发现了这样一个目录和文件,C:\BVTBin\Tests\installpackage\csilogfile.log,用于保存 CBS 的日志。要想起作用,必须先创建目录和文件。
一查,网也有好多人在说。
http://bbs.pcbeta.com/viewthread-838238-1-1.html
崩溃的原因可能还是由于调试模式与发行模式下堆的管理方式不同。
http://blog.csdn.net/zhengxh/article/details/6910548