标 题:
【原创】fmifs.dll导出函数参数分析和整理
作 者: raigeki
时 间: 2013-07-18,12:36:28
链 接: http://bbs.pediy.com/showthread.php?t=175653
(大牛飘过吧!~)
很久以前,发现一本叫逆向工程解密的书,当时,对于只会看MSDN的我和小伙伴们都惊呆了!居然可以通过逆向,分析出未文档化函数的接口参数,加以利用。果断瞧瞧,学习一把。后来我们碰到未文档化的函数时,我们都懂的……
上次发现fmifs.dll以及该动态链接库的导出函数,并且未文档化,我们也来分析一下。(大神曰:此dll功能强大!)转入正题……
分析未文档化函数的使用:
一般途径:
1、能找到一个系统中的调用例子,进行分析,这样可以看到该函数的参数具体形式(如SHFormatDrive中调用了FormatEx);
2、没有调用例子,通过分析该函数的代码,找出函数各个参数的使用限制,猜测参数的具体形式;
快捷途径:
1、搜索引擎,瞧瞧,有没有研究过,有直接拿过来就行;
2、某年某月,windows流出了古老的代码,过去翻翻,看有用得着的东西没有(这个的确快捷好用,别说,以前真不知道,那码怎么用,看哪里……);
走一般途径,各种锻炼;走快捷途径,各种速度;各种通吃也行,看你想要啥?……
该DLL共导出17个函数(应该说是16个,有一个初始化的fmifs的是DLLEntryPoint),从函数名可以看出,大致分为三类:查询xxx函数,设置xxx函数,具体操作xxx函数。
各种函数传参和返回时:
传入信息时,可以是字符串,或者各种标志信息标志信息中,可能一个DWORD只表示一种状态(如:enum 类型),也可能一个DWORD包含多种信息(如:CreateFile,中各种 标志1|标志2),就看这个DWORD是否涉及位运算;
返回信息时,一般是传入一个地址,然后通过指针往一个地址写东西,通过写的长度,可以判断这个指针所指缓冲区的大小。
分析时碰到的实例:
实例一:
代码:
char __stdcall QueryAvailableFileSystemFormat(unsigned int a1, void *a2, int a3, int a4, int a5)
{
memcpy(a2, (char *)&dword_696D5008 + 22 * a1, 2 * wcslen((const wchar_t *)&dword_696D5008 + 11 * a1) + 2);
*(_BYTE *)a3 = byte_696D501A[v6];
*(_BYTE *)a4 = byte_696D501B[v6];
*(_BYTE *)a5 = byte_696D501C[v6];
}
(IDA F5 插件,估计又被鄙视了!!
)很明显,a3,a4,a5是一个字节的输出缓冲区。a2,从memcpy最后一个参数,2*字符数+2(宽字符是两个字节表示一个字符),表示一个缓冲区。
实例二:
代码:
char __stdcall QueryDeviceInformation(int a1, int a2, unsigned int a3)
{
……
if ( (unsigned __int8)WSTRING__Initialize(&v6, a1, -1)&& ……)
{
……
*(_DWORD *)a2 = -(v8 != 0) & 0x10 | -(v9 != 0) & 0x41 | -((_BYTE)v10 != 0) & 0x20 | -(BYTE1(v10) != 0) & 0x40;
}
……
}
参数a1,和WSTRING_Initialize,a1是宽字串指针;看看a2的赋值,明显PDWORD,而且包含四个标志信息,一个标志信息一个字节。
实例三:
从上边两个例子的代码可以看出,参数大多是int(可以是指针,标志等),返回值是char(其实是BOOLEAN),而不是我们平时看到的各种HANDLE,XXX_TYPE,ULONG,BOOL,BOOLEAN,PWCHAR等。其实汇编代码里,知道的只是参数的长度(1字节,2字节,4字节等等),究其原因,其实是typedef、enum,#define等关键字,创建了各种各样华丽的包装,使得程序代码看起来生动活泼。汇编语言,因为不生动活泼,所以对其感兴趣的人都是一些寂寞的人。还有一个问题,因为函数传参是,都是push一次,4个字节,而不会出现push 一字节,所以,参数是否是小于四字节的类型,还需要根据代码中对该变量的操作来确定。
下面是一些函数的定义和调用注意事项(windows XP SP3 下的),调用不成功的就不贴了:
代码:
//QueryFileSystemName
typedef BOOLEAN (__stdcall *PQUERYFILESYSTEMNAME)(IN PWCHAR DriveName,
IN PWCHAR FileSystemName,
OUT PUCHAR MarjorVersion,//某种特定情况下才会返回版本信息
OUT PUCHAR MiniVersion,//某种特定情况下才会返回版本信息
OUT PDWORD Result);
//QueryLatestFileSystemVersion
typedef BOOLEAN (__stdcall *PQUERYLATESTFILESYSTEMVERSION)(IN PWCHAR DriveName,
OUT PUCHAR MarjorVersion,//总是返回版本信息
OUT PUCHAR MiniVersion);//总是返回版本信息
//QueryAvailableFileSystemFormat
typedef BOOLEAN (__stdcall *PQUERYAVAILABLEFILESYSTEMFORMAT)(IN FILESYS_TYPE FileType,//枚举类型0:FAT,1:FAT32,2:exFAT,3:NTFS4.0,4:NTFS5.0
OUT PWCHAR FileSystemName,
OUT PUCHAR MajorVersion,//总是返回版本信息
OUT PUCHAR MiniVersion,//总是返回版本信息
OUT PBOOLEAN Result);
//QueryDeviceInformation
typedef BOOLEAN (__stdcall *PQUERYDEVICEINFORMATION)(IN PWCHAR DriveName,
OUT PDWORD DeviceCharacter,//这一组属性解析应该需要很多define值
IN size_t nDeviceCharacter);
//QueryDeviceInformationByHandle
typedef BOOLEAN (__stdcall *PQUERYDEVICEINFORMATIONBYHANDLE)(IN HANDLE DriverHandle,
OUT PDWORD DeviceCharacter,//这一组属性解析应该需要很多define值
IN size_t nDeviceCharacter);
//QuerySupportedMedia
typedef BOOLEAN (__stdcall *PQUERYSUPPORTEDMEDIA)(IN PWCHAR DriveName,
OUT PDWORD pBuffer,//MEDIA_TYPE类型
IN size_t nBuffer,
OUT PDWORD Result);
//SetLabel
typedef BOOLEAN (__stdcall *PSETLABEL)(IN PWCHAR DriveName,
IN PWCHAR Label);
//EnableVolumeCompression
typedef BOOLEAN (__stdcall *PENABLEVOLUMECOMPRESSION)(IN PWCHAR VolumeDriver,
IN BOOLEAN CompressOrNot);
注:压缩功能只针对NTFS文件系统。
//Chkdsk
typedef VOID (__stdcall *PCHKDSK)(IN PWCHAR DriveName,
IN PWCHAR Format,
IN BOOLEAN CorrectErrors,
IN BOOLEAN Verbose,
IN BOOLEAN CheckOnlyIfDirty,
IN BOOLEAN Recover,
IN PWCHAR PathToCheck,
IN BOOLEAN Extend,
IN PFMIFSCALLBACK CallBack);
注:检查功能只针对FAT,FAT32文件系统。
//FormatEx
typedef VOID (__stdcall *PFORMATEX) (IN PWCHAR DriveName,
IN DWORD MediaFlag,
IN PWCHAR Format,
IN PWCHAR Label,
IN BOOL QuickFormat,
IN DWORD ClusterSize,
IN PFMIFSCALLBACK Callback);
//Format
typedef VOID (__stdcall *PFORMAT)(IN PWCHAR DriveName,
IN MEDIA_TYPE MediaType,
IN PWCHAR FileSysName,
IN PWCHAR Label,
IN BOOLEAN Quick,
IN PFMIFSCALLBACK CallBack);
//Extend
typedef BOOL (__stdcall *PEXTEND)(IN PWCHAR DriveName,
IN BOOLEAN Verify,
IN PFMIFSCALLBACK CallBack);
注:貌似只针对NTFS文件系统。
//DiskCopy
typedef BOOL (__stdcall *PDISKCOPY)(IN PWCHAR Src_Disk,
IN PWCHAR Dsk_Disk,
IN BOOLEAN Verify,
IN PFMIFSCALLBACK CallBack);
//ComputeFmMediaType
typedef MEDIA_TYPE (__stdcall *PCOMPUTEFMMEDIATYPE)(IN MEDIA_TYPE type);
//Fmifs CallBack
typedef BOOLEAN (__stdcall *PFMIFSCALLBACK)(FMIFS_PACKET_TYPE Command,
ULONG PackLength,
PVOID PackInfo);
关于MEDIA_TYPE定义,MSDN里面有的。直接拿过来了,发现比之前得到的版本多了好多:
代码:
typedef enum _MEDIA_TYPE {
Unknown = 0x00, //Format is unknown
F5_1Pt2_512 = 0x01, //A 5.25" floppy, with 1.2MB and 512 bytes/sector.
F3_1Pt44_512 = 0x02, //A 3.5" floppy, with 1.44MB and 512 bytes/sector.
F3_2Pt88_512 = 0x03, //A 3.5" floppy, with 2.88MB and 512 bytes/sector.
F3_20Pt8_512 = 0x04, //A 3.5" floppy, with 20.8MB and 512 bytes/sector.
F3_720_512 = 0x05, //A 3.5" floppy, with 720KB and 512 bytes/sector.
F5_360_512 = 0x06, //A 5.25" floppy, with 360KB and 512 bytes/sector.
F5_320_512 = 0x07, //A 5.25" floppy, with 320KB and 512 bytes/sector.
F5_320_1024 = 0x08, //A 5.25" floppy, with 320KB and 1024 bytes/sector.
F5_180_512 = 0x09, //A 5.25" floppy, with 180KB and 512 bytes/sector.
F5_160_512 = 0x0a, //A 5.25" floppy, with 160KB and 512 bytes/sector.
RemovableMedia = 0x0b, //Removable media other than floppy.
FixedMedia = 0x0c, //Fixed hard disk media.
F3_120M_512 = 0x0d, //A 3.5" floppy, with 120MB and 512 bytes/sector.
F3_640_512 = 0x0e, //A 3.5" floppy, with 640KB and 512 bytes/sector.
F5_640_512 = 0x0f, //A 5.25" floppy, with 640KB and 512 bytes/sector.
F5_720_512 = 0x10, //A 5.25" floppy, with 720KB and 512 bytes/sector.
F3_1Pt2_512 = 0x11, //A 3.5" floppy, with 1.2MB and 512 bytes/sector.
F3_1Pt23_1024 = 0x12, //A 3.5" floppy, with 1.23MB and 1024 bytes/sector.
F5_1Pt23_1024 = 0x13, //A 5.25" floppy, with 1.23MB and 1024 bytes/sector.
F3_128Mb_512 = 0x14, //A 3.5" floppy, with 128MB and 512 bytes/sector.
F3_230Mb_512 = 0x15, //A 3.5" floppy, with 230MB and 512 bytes/sector.
F8_256_128 = 0x16, //An 8" floppy, with 256KB and 128 bytes/sector.
F3_200Mb_512 = 0x17, //A 3.5" floppy, with 200MB and 512 bytes/sector. (HiFD).
F3_240M_512 = 0x18, //A 3.5" floppy, with 240MB and 512 bytes/sector. (HiFD).
F3_32M_512 = 0x19 //A 3.5" floppy, with 32MB and 512 bytes/sector.
} MEDIA_TYPE;
关于Fmifs pack type定义和各种包结构定义,参考windows NT4源码,windows兼容性就是好,数据结构扩展性极强,原来的东西都尽量保留 :
代码:
typedef enum _FMIFS_PACKET_TYPE {
FmIfsPercentCompleted,
FmIfsFormatReport,
FmIfsInsertDisk,
FmIfsIncompatibleFileSystem,
FmIfsFormattingDestination,
FmIfsIncompatibleMedia,
FmIfsAccessDenied,
FmIfsMediaWriteProtected,
FmIfsCantLock,
FmIfsCantQuickFormat,
FmIfsIoError,
FmIfsFinished,
FmIfsBadLabel,
FmIfsCheckOnReboot,
FmIfsTextMessage,
FmIfsHiddenStatus
} FMIFS_PACKET_TYPE, *PFMIFS_PACKET_TYPE;
typedef struct _FMIFS_PERCENT_COMPLETE_INFORMATION {
ULONG PercentCompleted;
} FMIFS_PERCENT_COMPLETE_INFORMATION, *PFMIFS_PERCENT_COMPLETE_INFORMATION;
typedef struct _FMIFS_FORMAT_REPORT_INFORMATION {
ULONG KiloBytesTotalDiskSpace;
ULONG KiloBytesAvailable;
} FMIFS_FORMAT_REPORT_INFORMATION, *PFMIFS_FORMAT_REPORT_INFORMATION;
typedef struct _FMIFS_INSERT_DISK_INFORMATION{
ULONG DiskType;
} FMIFS_INSERT_DISK_INFORMATION, *PFMIFS_INSERT_DISK_INFORMATION;
typedef struct _FMIFS_IO_ERROR_INFORMATION {
ULONG DiskType;
ULONG Head;
ULONG Track;
} FMIFS_IO_ERROR_INFORMATION, *PFMIFS_IO_ERROR_INFORMATION;
typedef struct _FMIFS_FINISHED_INFORMATION {
BOOLEAN Success;
} FMIFS_FINISHED_INFORMATION, *PFMIFS_FINISHED_INFORMATION;
typedef struct _FMIFS_CHECKONREBOOT_INFORMATION {
OUT BOOLEAN QueryResult; // TRUE for "yes", FALSE for "no"
} FMIFS_CHECKONREBOOT_INFORMATION, *PFMIFS_CHECKONREBOOT_INFORMATION;
typedef enum _TEXT_MESSAGE_TYPE {
MESSAGE_TYPE_PROGRESS,
MESSAGE_TYPE_RESULTS,
MESSAGE_TYPE_FINAL
} TEXT_MESSAGE_TYPE, *PTEXT_MESSAGE_TYPE;
typedef struct _FMIFS_TEXT_MESSAGE {
IN TEXT_MESSAGE_TYPE MessageType;
IN PSTR Message;
} FMIFS_TEXT_MESSAGE, *PFMIFS_TEXT_MESSAGE;
PS:差不多了,上面的说的和写的肯定有很多不足,欢迎拍砖!~,上面这些够用了,调用的代码我就不贴了。上次V大说的内个ChkdskEx,倒数第二个参数整不明白……没调用成功,貌似是一个结构体。