首页
社区
课程
招聘
[原创]Windows XP注册表文件格式简单分析
发表于: 2008-10-9 19:32 13839

[原创]Windows XP注册表文件格式简单分析

2008-10-9 19:32
13839
节省时间,我不把文章贴出来了,在二楼把代码贴出来,文件都在压缩包中:

运行结果:

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 7
支持
分享
最新回复 (9)
雪    币: 260
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define REGF                   0x66676572     //fger
#define HBIN                   0x6e696268     //nibh
#define CM_KEY_FAST_LEAF       0x666c         // fl
#define CM_KEY_HASH_LEAF       0x686c         // hl


//数据结构定义
typedef struct _CHILD_LIST
{
	ULONG Count;
	ULONG List;
}CHILD_LIST;

typedef struct _CM_KEY_NODE  
{ 
	USHORT  Signature;                
	CHAR  Reserve_1[18];
	ULONG SubKeyCounts[2];
	ULONG SubKeyLists[2];
	CHILD_LIST ValueList;
	CHAR  Reserve_2[28];
	USHORT NameLength;
	SHORT ClassName;
	CHAR  Name;
} CM_KEY_NODE,*PCM_KEY_NODE;

typedef struct _CM_KEY_INDEX
{
	USHORT Signature;
	USHORT Count;
	ULONG List[1];
} CM_KEY_INDEX, *PCM_KEY_INDEX;

typedef struct _CM_KEY_VALUE 
{ 
	USHORT  Signature;
	SHORT NameLength;
	ULONG DataLength; 
	ULONG Data;
	ULONG Type;
	CHAR  Reserve_1[4];
	CHAR  Name;
}CM_KEY_VALUE,*PCM_KEY_VALUE;


VOID TpyeKeyAndValue(PVOID FileMemAddr);
VOID TypeSubKey(PCHAR Bin,PCM_KEY_INDEX KeyIndex);
VOID TypeSubKeyName(PCHAR Bin,PCM_KEY_NODE KeyNode);
VOID TypeValue(PCHAR Bin,PCM_KEY_VALUE value);

int main(int argc,char *argv[])
{
	HANDLE hFile;
	HANDLE hFileMap;
	DWORD  FileSize;
	PVOID  FileMem;

#ifndef _DEBUG
	if(argc!=2)
	{
		printf("*************************\n");
		printf("Useage:\nHivePase FileName\n");
		printf("*************************\n");
		system("pause");
		return 1;
	}
	hFile=CreateFile(argv[1],GENERIC_READ,0,NULL,
					OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
#else
	hFile=CreateFile("c:\\test_root.dat",GENERIC_READ,0,NULL,
					OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
#endif

	if(hFile==INVALID_HANDLE_VALUE)
	{
		printf("Error:File doesn's Exist!\n");
		system("pause");
		return 1;
	}
	FileSize=GetFileSize(hFile,NULL);
	hFileMap=CreateFileMapping(hFile,NULL,PAGE_READONLY | SEC_COMMIT,0,FileSize,NULL);
	if(hFileMap==NULL)
	{
		printf("CreateFileMapping Error!\n");
		CloseHandle(hFile);
		system("pause");
		return 1;
	}
	CloseHandle(hFile);
	FileMem=MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,0);
	if(FileMem==NULL)
	{
		printf("MapViewOfFile Error!\n");
		CloseHandle(hFileMap);
		system("pause");
		return 1;
	}
	CloseHandle(hFileMap);
	TpyeKeyAndValue(FileMem);
	printf("\nSuccess!\n");
	system("pause");
	return 0;
}

VOID TpyeKeyAndValue(PVOID FileMemAddr)
{
	char RootKeyName[256];
	PCHAR RootBin;
	PCM_KEY_NODE KeyNode;
	PCM_KEY_INDEX KeyIndex;
	if(*(ULONG*)FileMemAddr!=REGF)
	{
		printf("Not a Hive File!\n");
		system("pause");
	}
	RootBin=(char*)FileMemAddr+0x1000;
	KeyNode=(PCM_KEY_NODE)(RootBin+0x24);
	if(*(ULONG*)RootBin!=HBIN)
	{
		printf("Hive File Error!\n");
		system("pause");
	}
	ZeroMemory(RootKeyName,256);
	strncpy(RootKeyName,&KeyNode->Name,KeyNode->NameLength);
	printf("Root Key:	%s\n",RootKeyName);
	DWORD SubKeyLists=KeyNode->SubKeyLists[0];
	KeyIndex=(PCM_KEY_INDEX)(RootBin+SubKeyLists+0x4);
	TypeSubKey(RootBin,KeyIndex);

}

VOID TypeSubKey(PCHAR Bin,PCM_KEY_INDEX KeyIndex)
{
	USHORT KeyCount;
	PCM_KEY_NODE KeyNode;
	KeyCount=KeyIndex->Count;
	for(USHORT i=0;i<KeyCount;i++)
	{
		if(KeyIndex->Signature==CM_KEY_FAST_LEAF || KeyIndex->Signature==CM_KEY_HASH_LEAF)
		{
			DWORD KeyNodeOffset=KeyIndex->List[i*2];
			KeyNode=(PCM_KEY_NODE)(Bin+KeyNodeOffset+0x4);
			TypeSubKeyName(Bin,KeyNode);
		}
		else
		{
			DWORD KeyNodeOffset=KeyIndex->List[i*2];
			KeyNode=(PCM_KEY_NODE)(Bin+KeyNodeOffset+0x4);
			TypeSubKeyName(Bin,KeyNode);
		}
	}

}

VOID TypeSubKeyName(PCHAR Bin,PCM_KEY_NODE KeyNode)
{
	char SubKeyName[256];
	ULONG ValueLists;
	ULONG ValueCount;
	ULONG *ValueIndex;
	PCM_KEY_VALUE value;
	PCM_KEY_INDEX KeyIndex;
	ZeroMemory(SubKeyName,256);
	strncpy(SubKeyName,&KeyNode->Name,KeyNode->NameLength);
	printf("Sub Key:	%s\n",SubKeyName);
	ValueLists=KeyNode->ValueList.List;
	ValueCount=KeyNode->ValueList.Count;
	if(ValueLists!=-1)
	{
		ValueIndex=(ULONG *)(Bin+ValueLists+0x4);
		for(ULONG i=0;i<ValueCount;i++)
		{
			value=(PCM_KEY_VALUE)(Bin+ValueIndex[i]+0x4);
			TypeValue(Bin,value);
		}
	}
	if(KeyNode->SubKeyLists[0]!=-1)
	{
		KeyIndex=(PCM_KEY_INDEX)(Bin+KeyNode->SubKeyLists[0]+0x4);
		TypeSubKey(Bin,KeyIndex);
	}
}


VOID TypeValue(PCHAR Bin,PCM_KEY_VALUE value)
{
	char ValueName[256];
	ULONG DataLenth;
	PCHAR Data;
	ZeroMemory(ValueName,256);
	strncpy(ValueName,&value->Name,value->NameLength);
	printf("Value Name:	%s\n",ValueName);
	switch(value->Type)
	{
		case REG_SZ:
			printf("REG_SZ		");
			break;
		case REG_BINARY:
			printf("REG_BINARY	");
			break;
		case REG_DWORD:
			printf("REG_DWORD	");
			break;
		case REG_MULTI_SZ:
			printf("REG_MULIT_SZ	");
			break;
		case REG_EXPAND_SZ:
			printf("REG_EXPAND_SZ	");
			break;
		default:
			break;
	}
	if(value->Type==REG_DWORD)
	{
		Data=(PCHAR)&value->Data;
		printf("%08x",*(ULONG*)Data);
	}
	else
	{
		if(value->DataLength & 0x80000000)
		{
			DataLenth=value->DataLength & 0x7FFFFFFF;
			Data=(PCHAR)&value->Data;
			for(ULONG i=0;i<DataLenth;i++)
			{
				if(value->Type==REG_BINARY)
				{
					printf("%1x",Data[i]);
				}
				else
				{
					printf("%c",Data[i]);
				}
			}
		}
		else
		{
			DataLenth=value->DataLength;
			DWORD DataOffset=value->Data;
			Data=Bin+DataOffset+0x4;
			for(ULONG i=0;i<DataLenth;i++)
			{
				if(value->Type==REG_BINARY)
				{
					printf("%1x",Data[i]);
				}
				else
				{
					printf("%c",Data[i]);
				}
			}
		}
	}
	printf("\n");
}

2008-10-9 19:34
0
雪    币: 234
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
好东西!
这些研究很需要功力!
2008-10-9 20:25
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
4
顶一下楼主,注册表这东西是比较复杂!
2008-10-9 20:34
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
用API能直接做。
2008-10-10 21:35
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6
为什么我看到#5总是想骂人?

做的不错  不过看那些struct定义,可能做的不完全。
2008-10-10 21:59
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
7
API直接做...说明你还不知道这东西的意义...哈哈  从安全的角度讲//API是不安全的...
2008-10-10 22:30
0
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
8
不错 学习下
不过好像 有点问题
1.对nk节点下二级索引子键的情况没有处理(有ri节点情况,当子键过多的时候系统会使用ri节点的)
2.TypeValue里对值名称的处理有问题,问题出在这下面两行代码
     strncpy(ValueName,&value->Name,value->NameLength);
     printf("Value Name:  %s\n",ValueName);
vk节点的值名称未必就是ascii字符串,因此用str系列函数是不可以的,正确用法应该是
     memcpy(ValueName,&value->Name,value->NameLength);因此显示语句也不能用printf来显示,目前我看到的很多代码都有这样的问题(chntpw),还有一些使用的hive解析的工具(SnipeSword0225)也有这种问题
2008-10-11 10:20
0
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
9
再说两句
HIVE出来的东西 用网上流传一些代码解析出来的hive未必可信
至少我目前看到的情况 是会有少子键的情况  当然并不是说解析代码的问题 而是hive文件里根本就没有那个子键的信息  具体原因不清楚(还没搞明白)  不知道是不是我导出HIVE的方法不正确
有知道 解决方法的同学   可以贡献下 贴出来
2008-10-11 10:27
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
10
已经习惯了用CMLIB了~Hive不一定能Flush整个进来~
2008-10-11 10:58
0
游客
登录 | 注册 方可回帖
返回
//