Decompiled msinst.exe

本文介绍了一个逆向工程案例,针对msinst.exe程序进行了解析,并详细解释了其工作流程,包括检查目标驱动器、验证分区信息及扇区可用性等。此外,还提供了将指定扇区间数据复制到文件的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Decompiled msinst.exe

 

msinst.exe 用来将IPL安装到memorystick上的程序。他的工作流程:

1.      检查用户所指定的盘符是否对应一个移动设备(避免不小心干掉系统盘之类)

2.      检查从memory stick第16个扇区开始到绝对扇区之间是否有足够的空间来容纳IPL

3.      如果上面的检查通过,将IPL从第16个扇区开始写入

 

下面是逆向出来的代码,加入了将指定的扇区之间的数据复制到文件的功能。

/*
===============================================================
The original msinst.exe console output:
---------------------------------------------------------------
PSP MS IPL Installer
Load IPL code pspboot.bin
15630 bytes(4 block) readed

Target DRIVE is 1
Check partation Sector
boot status        0x80
start head         0x00
start sec/cyl    0x0401
partation type     0x0B
last head          0xFE
last sec/cyl     0x823F
abs sector   0x0000FB04
ttl sector   0x001F21BF
signature        0xAA55
Check BPB Sector
signature        AA55
Check free reserved sector:OK
Write ABS Sector 0x10 to 0x2F
Are You Sure ?[Y]n
===============================================================
*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define SECTOR_SIZE 512

typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned int u32;

char RootPathName[256];
char FileName[256];
u8 data[0x100000];

/* 
===============================================================
GetDriveType
for c: will reture 3
#define DRIVE_REMOVABLE   2
#define DRIVE_FIXED       3
===============================================================
DeviceIoControl
command 0x560000 get data
g:
0x0012FE38  01 00 00 00 00 00 00 00 01 00 00 00 b0 35 21 86  .............5!.
0x0012FE48  00 08 f6 01 00 00 00 00 00 7e 43 3e 00 00 00 00  .........~C>....
c:
0x0012FE38  01 00 00 00 a8 80 27 86 00 00 00 00 a0 80 27 86  .....€'......€'.
0x0012FE48  00 7e 00 00 00 00 00 00 00 02 02 88 13 00 00 00  .~..............
d:
0x0012FE38  01 00 00 00 f4 c3 41 94 00 00 00 00 01 00 04 00  ......A.........
0x0012FE48  00 fe 02 88 13 00 00 00 00 a2 02 6a 18 00 00 00  ...........j....
e:
0x0012FE38  01 00 00 00 e0 97 e3 85 00 00 00 00 56 00 43 00  ............V.C.
0x0012FE48  00 1e 06 f2 2b 00 00 00 00 02 a0 93 1e 00 00 00  ....+...........
===============================================================
*/
int  read_sector(u32 devid, int offset, int cnt, LPVOID lpBuffer)
{
	int result;
	HANDLE hFile;
	DWORD dwRet;

	sprintf(FileName, "%s%d", "\\\\.\\PHYSICALDRIVE", devid);
	if (devid){
		hFile = CreateFile(FileName, 0x80000000u, 1u, 0, 3u, 0, 0);
		if ( hFile == (HANDLE)-1 ){
			printf("[erro] Cannot open device %s\n", FileName);
			result = -1;
		}else{
			if (SetFilePointer(hFile, offset*SECTOR_SIZE, 0, 0) == (offset*SECTOR_SIZE)){
				if ( ReadFile(hFile, lpBuffer, cnt*SECTOR_SIZE, &dwRet, 0) == 1 ){
					CloseHandle(hFile);
					result = 0;
				}else{
					printf("[erro] Error in ReadFile.\n");
					CloseHandle(hFile);
					result = -1;
				}
			}else{
				printf("[erro] Error setting filepointer.\n");
				CloseHandle(hFile);
				result = -1;
			}
		}
	}else{
		printf("[erro] Drive 0 failsafe.\n");
		result = -1;
	}
	return result;
}


int write_sector(u32 devid, int offset, int cnt, LPCVOID lpBuffer)
{
	int result;
	HANDLE hFile;
	DWORD dwRet;

	sprintf(FileName, "%s%d", "\\\\.\\PHYSICALDRIVE", devid);
	if (devid){
		hFile = CreateFile(FileName, 0xC0000000u, 1u, 0, 3u, 0, 0);
		if ( hFile == (HANDLE)-1 ){
			printf("[erro] Cannot open device %s\n", FileName);
			return -1;
		}else{
			if (SetFilePointer(hFile, offset*SECTOR_SIZE, 0, 0) == (offset*SECTOR_SIZE)){
				if ( WriteFile(hFile, lpBuffer, cnt*SECTOR_SIZE, &dwRet, 0) == 1 ){
					CloseHandle(hFile);
					result = 0;
				}else{
					printf("[erro] Error in WriteFile.\n");
					CloseHandle(hFile);
					result = -1;
				}
			}else{
				printf("[erro] Error setting filepointer.\n");
				CloseHandle(hFile);
				result = -1;
			}
		}
	}else{
		printf("[erro] Drive 0 failsfe.\n");
		result = -1;
	}
	return result;
}


int dump_sector(int devid, int start, int end)
{
	u8 *buf;
	FILE *fp;
	int buf_size;

	fp = fopen("dump.bin", "wb");
	if(NULL == fp){
		printf("[erro] Error to open file [%s]\n", "dump.bin");
		return -1;
	}
	buf_size = (end-start+1)*SECTOR_SIZE;
	buf = (u8 *)malloc(buf_size);
	read_sector(devid, start, end-start+1, (void*)buf);
	fwrite(buf, buf_size, 1, fp);
	free(buf);
	fclose(fp);
}

int load_payload(char *fname)
{
	FILE* fp;
	int file_size;
	fp = fopen(fname, "rb");
	if(NULL == fp){
		printf("[erro] open datafile [%s] failed\n", fname);
		return -1;
	}
	fseek(fp, 0, SEEK_END);
	file_size = ftell(fp);
	fseek(fp, 0, 0);
	fread(data, file_size, 1, fp);
	fclose(fp);
	return file_size;
}

int check_removable(char lable)
{
	int dev_type = 0;
	DWORD dwOutput;
	HANDLE file;
	HRESULT ret;

	unsigned char OutBuffer[0x20];
	sprintf(RootPathName, "%c:\\", lable);
	dev_type = GetDriveType(RootPathName);
	if(DRIVE_REMOVABLE != dev_type){
		printf("[erro] Drive %c is invalid or not removable\n", lable);
		return -1;
	}
	sprintf(RootPathName, "\\\\.\\%c:", lable);
	file = CreateFile(RootPathName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
	if ( file == (HANDLE)-1 ){
		printf("[erro] Cannot open logical drive.\n");
		return -1;
	}
	ret = DeviceIoControl(file, 0x560000, 0, 0, OutBuffer, 0x20, &dwOutput, 0);
	if ( GetLastError() == 234 || *(u32 *)OutBuffer != 1 ){
		printf("[erro] Logical drive has more than a physical drive. Cannot handle it.\n");
		CloseHandle(file);
		return -1;
	}
	if(0 == ret){
		printf("[erro] Error 0x%08X in DeviceIoControl.\n", 0);
		CloseHandle(file);
		return -1;
	}
	CloseHandle(file);
	return *(u32*)(OutBuffer+8);
}

int main(int argc, char* argv[])
{
	int devid, ldrscnt=4, abs_sec=0, ldrsize;
	u8 buf[SECTOR_SIZE];
	ldrsize = load_payload("ipl_ms.bin");
	if(ldrsize<0) return -1;
	
	//calc block cnt for 4KB
	ldrscnt = (signed int)(ldrsize + 4095) / 4096;
	devid = check_removable('g');
	if(devid<0) return -1;
	printf("\nTarget DRIVE is %d\n", devid);
	printf("Check partation Sector\n");
	if(read_sector(devid, 0, 1, (void*)buf) < 0){
		printf("[erro] Can't read partation sector\n");
		return -1;
	}
	abs_sec = *(u16 *)(buf+0x1c6);
	printf("boot status        0x%02X\n", *(u8 *)(buf+0x1be));
	printf("start head         0x%02X\n", *(u8 *)(buf+0x1bf));
	printf("start sec/cyl    0x%04X\n", *(u16 *)(buf+0x1c0));
	printf("partation type     0x%02X\n", *(u8 *)(buf+0x1c2));
	printf("last head          0x%02X\n", *(u8 *)(buf+0x1c3));
	printf("last sec/cyl     0x%04X\n", *(u16 *)(buf+0x1c4));
	printf("abs sector   0x%08X\n", abs_sec);
	printf("ttl sector   0x%08X\n", *(u32 *)(buf+0x1ca));
	printf("signature        0x%04X\n", *(u16 *)(buf+0x1fe));

	if( *(u16 *)(buf+0x1fe) != 0xAA55 ){
		printf("[erro] Bad Signature\n");
		return -1;
	}
	printf("Check BPB Sector\n");
	if ( read_sector(devid, *(u16 *)(buf+0x1c6), 1, (void*)buf) >= 0 ){
		printf("signature        0x%04X\n", *(u16 *)(buf+0x1fe));
		if( *(u16 *)(buf+0x1fe) != 0xAA55 ){
			printf("[erro] Bad Signature\n");
			return -1;
		}
		printf("Check free reserved sector:");
		if((abs_sec - 16)/8<ldrscnt){
			printf("[erro] to small reserved sectors\n");
			return -1;
		}
		printf("OK\n");
		//printf("Write ABS Sector 0x%X to 0x%X\n", 16, 8*ldrscnt+15);
		//write_sector(devid, 16, 8*ldrscnt, data);
		
		printf("Dump ABS Sector 0x%X to 0x%X\n", 0x40, 0x47);
		dump_sector(devid, 0x40, 0x47);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值