📄 fileio.cpp
字号:
/*++
Copyright (c) 2002 Sten
Contact information:
mail: stenri@mail.ru
This code is based on mamaich's IceLib.cpp code (see IceX src).
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Module Name:
fileio.cpp
Abstract: Implements file dumping functions.
Revision History:
Sten 05/06/2002
Initial release
--*/
extern "C" {
#pragma warning ( push, 3 )
#include <ntddk.h>
#pragma warning ( pop )
}
#pragma warning ( disable: 4514 ) // unreferenced inline function has been removed
#pragma warning ( disable: 4127 ) // conditional expression is constant
#include "defs.h"
#include "wdbgexts.h"
DECLARE_API (resume);
/////////////////////////////////////////////////////////////////////////////
//
// Thread which executes a specified function at IRQL==PASSIVE_LEVEL
// I do not use work items or DPCs because they execute immediately
// inside SoftIce when current IRQL<DISPATCH_LEVEL (and I need func to
// be executed after SoftIce exit)
//
/////////////////////////////////////////////////////////////////////////////
#define MAXFUNCS 10
HANDLE Thread;
KEVENT *EvExec;
struct CallF
{
void (*Func)(void *Arg);
void *Arg;
};
static CallF CallFunc[MAXFUNCS];
void ThreadProc(void*)
{
LARGE_INTEGER t;
*(__int64*)&t=-10000000L;
DbgPrint("THD: Worker thread created\n");
while(1)
{
KeWaitForSingleObject(EvExec, Executive, KernelMode,0,0);
KeResetEvent(EvExec);
for(int i=0; i<MAXFUNCS; i++)
{
if(CallFunc[i].Func)
{
void (*Tmp)(void*)=CallFunc[i].Func;
void *P=CallFunc[i].Arg;
CallFunc[i].Func=0; // To allow CallFunc enter & shedule other function
Tmp(P);
}
}
}
}
void InitThread()
{
EvExec=(KEVENT*)ExAllocatePool(NonPagedPool,sizeof(KEVENT));
KeInitializeEvent(EvExec,NotificationEvent,FALSE);
PsCreateSystemThread(&Thread, THREAD_ALL_ACCESS, 0,
0, 0, ThreadProc, 0);
}
/////////////////////////////////////////////////////////////////////////////
//
// Shedule the function to be executed after SoftIce exit with parameter Arg
// Maximum MAXFUNCS are allowed to be sheduled
//
/////////////////////////////////////////////////////////////////////////////
void Shedule(void (*Func)(void*), void *Arg)
{
for(int i=0; i<MAXFUNCS; i++)
{
if(CallFunc[i].Func==0)
{
CallFunc[i].Func=Func;
CallFunc[i].Arg=Arg;
KeSetEvent(EvExec,0,FALSE);
return;
}
}
DbgPrint("Shedule: too many funcions sheduled. Increase MAXFUNCS\n");
}
/////////////////////////////////////////////////////////////////////////////
//
// Internal - dumps memory to the file.
//
/////////////////////////////////////////////////////////////////////////////
struct FileToDump
{
char FileName[260];
void *Buf;
size_t Size;
};
void DumpFile(void *F)
{
FileToDump *FTD=(FileToDump*)F;
if(FTD==0 || FTD->FileName==0)
{
DbgPrint("DumpFile: invalid FTL structure. Unable to dump file!\n");
return;
}
DbgPrint("DumpFile: Duming file '%s'\n", FTD->FileName);
HANDLE hFile=0;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING unicodeFullName;
OBJECT_ATTRIBUTES objectAttributes;
ANSI_STRING as;
RtlInitAnsiString(&as, FTD->FileName);
RtlAnsiStringToUnicodeString(&unicodeFullName, &as, TRUE);
InitializeObjectAttributes( &objectAttributes,
&unicodeFullName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NTSTATUS ntStatus = ZwCreateFile( &hFile,
GENERIC_WRITE | SYNCHRONIZE,
&objectAttributes,
&ioStatus,
0,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_SUPERSEDE, // Warning: replace file if exists
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint("DumpFile: error creating file %08X\n", ntStatus);
return;
}
ZwWriteFile(hFile,
NULL,
NULL,
NULL,
&ioStatus,
FTD->Buf,
FTD->Size,
NULL,
NULL);
ZwClose(hFile);
RtlFreeUnicodeString(&unicodeFullName);
ExFreePool(FTD->Buf); // Buf should be allocated!!
ExFreePool(F); // F should be allocated!!
}
/////////////////////////////////////////////////////////////////////////////
//
// Shedules the file dumping.
//
/////////////////////////////////////////////////////////////////////////////
void SheduleDumpFile(char *FileName, void *Addr, int Size)
{
FileToDump *FTD=(FileToDump*)ExAllocatePool(NonPagedPool, sizeof(FileToDump));
memset(FTD,0,sizeof(FileToDump));
strncpy(FTD->FileName,FileName,259);
FTD->Buf = Addr;
FTD->Size = Size;
Shedule(DumpFile, FTD);
}
/////////////////////////////////////////////////////////////////////////////
//
// Internal - loads the file.
//
//
/////////////////////////////////////////////////////////////////////////////
struct FileToLoad
{
char FileName[260];
void **FileBuffer;
int *FileSize;
};
void LoadFile(void*F)
{
HANDLE hFile=0;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING unicodeFullName;
OBJECT_ATTRIBUTES objectAttributes;
NTSTATUS ntStatus;
ANSI_STRING as;
FileToLoad *FTL=(FileToLoad*)F;
if(FTL==0 || FTL->FileName==0)
{
DbgPrint("LoadFile: invalid FTL structure. Unable to load file!\n");
goto cleanup2;
}
*FTL->FileBuffer=0;
*FTL->FileSize=0;
DbgPrint("LoadFile: Loading file '%s'\n",FTL->FileName);
RtlInitAnsiString(&as, FTL->FileName);
ntStatus = RtlAnsiStringToUnicodeString(&unicodeFullName, &as, TRUE);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint("Unable to initialize unicode string.\n",ntStatus);
goto cleanup2;
}
InitializeObjectAttributes( &objectAttributes,
&unicodeFullName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
ntStatus = ZwOpenFile( &hFile,
GENERIC_READ | SYNCHRONIZE,
&objectAttributes,
&ioStatus,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint("LoadFile: error opening file %08X\n",ntStatus);
goto cleanup;
}
FILE_STANDARD_INFORMATION eof;
ntStatus = ZwQueryInformationFile(hFile, &ioStatus, &eof, sizeof(eof),
FileStandardInformation);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint("LoadFile: error getting file size %08X\n", ntStatus);
goto cleanup;
}
*FTL->FileBuffer = 0;
*FTL->FileSize=eof.EndOfFile.LowPart;
*FTL->FileBuffer=(char*)ExAllocatePool(NonPagedPool,eof.EndOfFile.LowPart+1);
if (!(*FTL->FileBuffer))
{
DbgPrint("LoadFile: error allocating %08X bytes\n", NonPagedPool,eof.EndOfFile.LowPart+1);
goto cleanup;
}
((char*)(*FTL->FileBuffer))[*FTL->FileSize]=0; // make the buffer ASCIIZ
if(*FTL->FileBuffer==0)
{
DbgPrint("LoadFile: not enough memory in NonPagedPool to allocate % bytes",
*FTL->FileSize);
goto cleanup;
}
ZwReadFile(hFile,
NULL,
NULL,
NULL,
&ioStatus,
*FTL->FileBuffer,
*FTL->FileSize,
NULL,
NULL);
DbgPrint("File loaded at: %08x\n", *FTL->FileBuffer);
DbgPrint("File size is : %08x\n", *FTL->FileSize);
cleanup:
RtlFreeUnicodeString(&unicodeFullName);
cleanup2:
ZwClose(hFile);
ExFreePool(F); // F should be allocated!!
resume(0, 0, 0, 0, NULL);
return;
}
/////////////////////////////////////////////////////////////////////////////
//
// Shedules the file loading. While file loading is in queue *Size==-1.
// After loading it will contain the real size, or 0 if error.
//
/////////////////////////////////////////////////////////////////////////////
void SheduleReadFile(char *FileName, void **ReadHere, int *Size)
{
FileToLoad *FTL=(FileToLoad*)ExAllocatePool(NonPagedPool, sizeof(FileToLoad));
memset(FTL,0,sizeof(FileToLoad));
strncpy(FTL->FileName,FileName,259);
FTL->FileBuffer=ReadHere;
*(PULONG)ReadHere=0;
if(Size==0) // No dwSize specified
{
static tmp;
Size=&tmp;
}
FTL->FileSize=Size;
*Size=-1;
Shedule(LoadFile,FTL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -