BOOL DupFile( LPCTSTR lpFileName , int pid )
{
BOOL bRedup;
HANDLE hFile,hProcess;
HANDLE hTargetHandle;
EnablePrivilege(SE_DEBUG_NAME,TRUE);
if(ProcessList(pid)) printf("Process Name: %s\n",szProcessName);
hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, pid);
if ( hProcess == NULL )
{
printf("PROCESS_DUP_HANDLE Error\n");
return FALSE;
}
hFile = CreateFile( lpFileName,
GENERIC_READ,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("CreateFile Error\n");
CloseHandle( hProcess );
return FALSE;
}
bRedup = DuplicateHandle( GetCurrentProcess(),
hFile,
hProcess,
&hTargetHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);
CloseHandle( hProcess );
return bRedup;
}
/********************************************************************
filename: e:\C++\VS2008\dhfile_MY\dhfile_MY\dhfile.cpp
file path: e:\C++\VS2008\dhfile_MY\dhfile_MY
file base: dhfile
file ext: cpp
completed: 7.7 0:15
author: nevergone
purpose: practice for reverseing
original author : 风泽
*********************************************************************/
#include
#include
#include
#include
#include "ntdll/ntdll.h"
#pragma comment(lib, "ntdll.lib")
#pragma warning(disable : 4996)
using namespace std;
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
char g_szProcessName[MAX_PATH];
HANDLE g_hProcessHeap;
struct HANDLE_NAME
{
HANDLE hFile;
FILE_NAME_INFORMATION file_info;
};
//
// this function come from KILL_KIS8
//
PVOID GetSystemInformation(SYSTEM_INFORMATION_CLASS iSystemInformationClass)
{
ULONG ulSize = 0x8000;
ULONG ulRequired;
LPVOID pvBuffer;
NTSTATUS Status;
do {
pvBuffer = HeapAlloc(GetProcessHeap(), 0, ulSize);
if (!pvBuffer)
return NULL;
Status = NtQuerySystemInformation(iSystemInformationClass,
pvBuffer,
ulSize,
&ulRequired);
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(GetProcessHeap(), 0, pvBuffer);
ulSize *= 2;
}
} while(Status == STATUS_INFO_LENGTH_MISMATCH);
if (NT_SUCCESS(Status))
return pvBuffer;
HeapFree(GetProcessHeap(), 0, pvBuffer);
return NULL;
}
DWORD WINAPI GetFileNameThreadProc(LPVOID pvParam)
{
IO_STATUS_BLOCK io_status;
HANDLE hFile = *(LPHANDLE)pvParam;
PVOID pvBuffer = (PVOID)((DWORD)pvParam + sizeof(HANDLE));
NtQueryInformationFile(hFile,
&io_status,
pvBuffer,
528,
FileNameInformation);
return 0;
}
INT GetFileNameByHandle(HANDLE hFile, LPSTR lpMultiByteStr)
{
PVOID pvBuffer = HeapAlloc(g_hProcessHeap, HEAP_ZERO_MEMORY, 532);
*((LPDWORD)pvBuffer) = (DWORD)hFile;
HANDLE hThread = CreateThread(NULL,
0,
GetFileNameThreadProc,
pvBuffer,
0,
NULL);
//
// 100 may be too short for some slow machine~
//
DWORD dwRet = WaitForSingleObject(hThread, 100);
if (dwRet == WAIT_TIMEOUT)
TerminateThread(hThread, 0);
CloseHandle(hThread);
PFILE_NAME_INFORMATION pFileNameInfo = (PFILE_NAME_INFORMATION)((DWORD)pvBuffer + sizeof(HANDLE));
WideCharToMultiByte(CP_ACP,
0,
pFileNameInfo->FileName,
pFileNameInfo->FileNameLength / 2,
lpMultiByteStr,
MAX_PATH,
NULL,
NULL);
HeapFree(g_hProcessHeap, 0, pvBuffer);
return 0;
}
UCHAR GetFileObjectTypeNumber()
{
UCHAR uchar_ObjectTypeNumber = 0;
HANDLE hFile = CreateFileA("NUL",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
0);
if (hFile == INVALID_HANDLE_VALUE)
return 0;
LPVOID pvBuffer = GetSystemInformation(SystemHandleInformation);
if (pvBuffer == NULL)
{
CloseHandle(hFile);
return 0;
}
DWORD dwCount = ((PSYSTEM_HANDLE_INFORMATION_EX)pvBuffer)->NumberOfHandles;
if (!dwCount)
{
HeapFree(g_hProcessHeap, 0, pvBuffer);
CloseHandle(hFile);
return 0;
}
PSYSTEM_HANDLE_INFORMATION pHandleInfo = ((PSYSTEM_HANDLE_INFORMATION_EX)pvBuffer)->Information;
for (DWORD i = 0; i < dwCount; ++i)
{
if (pHandleInfo[i].Handle == (USHORT)hFile &&
pHandleInfo[i].ProcessId == GetCurrentProcessId())
{
uchar_ObjectTypeNumber = pHandleInfo[i].ObjectTypeNumber;
HeapFree(g_hProcessHeap, 0, pvBuffer);
CloseHandle(hFile);
return uchar_ObjectTypeNumber;
}
}
return 0;
}
BOOL EnableDebugPrivilge(LPCSTR lpName, BOOL fEnable)
{
HANDLE hObject;
LUID Luid;
TOKEN_PRIVILEGES NewStatus;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hObject))
return FALSE;
if (LookupPrivilegeValue(NULL, lpName, &Luid))
{
NewStatus.Privileges[0].Luid = Luid;
NewStatus.PrivilegeCount = 1;
NewStatus.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hObject, FALSE, &NewStatus, 0, 0, 0);
CloseHandle(hObject);
return TRUE;
}
return FALSE;
}
BOOL GetProcessNameById(DWORD dwProcessId)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
0);
//
// add by nevergone
//
if (hSnapshot == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot error\n");
return 0;
}
PROCESSENTRY32 pe;
PCHAR pProcessName = NULL;
//
// add by nevergone. Process32First may be failed if without setting the size
//
pe.dwSize = sizeof(pe);
if (!Process32First(hSnapshot, &pe))
{
CloseHandle(hSnapshot);
return FALSE;
}
do {
pProcessName = strrchr(pe.szExeFile, '\\');
if (pProcessName)
pProcessName++;
else
pProcessName = pe.szExeFile;
if (pe.th32ProcessID == dwProcessId)
{
ZeroMemory(g_szProcessName, sizeof(g_szProcessName));
strncpy(g_szProcessName, pProcessName, lstrlen(pProcessName));
//
//add by nevergone
//
CloseHandle(hSnapshot);
return TRUE;
}
} while(Process32Next(hSnapshot, &pe));
CloseHandle(hSnapshot);
return FALSE;
}
BOOL ProtectFile(LPCSTR lpFileName, DWORD dwProcessId)
{
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
if (!hProcess)
{
printf("PROCESS_DUP_HANDLE Error\n");
return FALSE;
}
HANDLE hFile = CreateFile(lpFileName,
GENERIC_READ,
0,
NULL,
/*OPEN_ALWAYS*/OPEN_EXISTING, // OPEN_EXISTING may be better [nevergone]
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile Error\n");
CloseHandle(hFile);
return FALSE;
}
BOOL fOk = DuplicateHandle(GetCurrentProcess(),
hFile,
hProcess,
NULL,
0,
FALSE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
CloseHandle(hProcess);
return fOk;
}
int Process(int iUnknown, char *pString1, char *pString2)
{
UCHAR uchar_FileTypeNumber;
PVOID pvoid_HandleInfo;
DWORD dwHandleCount;
PSYSTEM_HANDLE_INFORMATION pHandleInfo;
HANDLE hProcess;
HANDLE hTarget;
PCHAR pszPath;
DWORD dwCount = 0;
CHAR szFilePath[MAX_PATH] = { 0 };
g_hProcessHeap = GetProcessHeap();
uchar_FileTypeNumber = GetFileObjectTypeNumber();
pvoid_HandleInfo = GetSystemInformation(SystemHandleInformation);
if (pvoid_HandleInfo == NULL)
return 0;
dwHandleCount = *(LPDWORD)pvoid_HandleInfo;
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((DWORD)pvoid_HandleInfo + sizeof(HANDLE));
if (!dwHandleCount)
{
HeapFree(g_hProcessHeap, 0, pvoid_HandleInfo);
printf("Not found File %s \n", pString1);
return 0;
}
for (DWORD i = 0; i < dwHandleCount; ++i)
{
if (pHandleInfo[i].ObjectTypeNumber != uchar_FileTypeNumber)
continue;
if (iUnknown == pHandleInfo[i].ProcessId ||
_strnicmp(pString2, "/f", 2) == 0)
{
// ToDo:
hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pHandleInfo[i].ProcessId);
if (hProcess == NULL)
continue;
BOOL fOk = DuplicateHandle(hProcess,
(HANDLE)pHandleInfo[i].Handle,
GetCurrentProcess(),
&hTarget,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
if (!fOk)
{
CloseHandle(hProcess);
continue;
}
//
// add by nevergone, this is important. if GetFileNameThreadProc failed to
// get the file path, then WideCharToMultiByte do nothing with
// lpMultiByteStr parameter[see Test Project for detail],
// but lpMultiBytePtr is set by the previous GetFileNameByHandle. so must zero szFilePath.
//
ZeroMemory(szFilePath, sizeof(szFilePath));
GetFileNameByHandle(hTarget, szFilePath);
pszPath = szFilePath;
if (pszPath = strrchr(szFilePath, '\\'))
pszPath++;
else
pszPath = szFilePath;
if (_strnicmp(pString2, "/l", 2) == 0)
{
++dwCount;
printf("Handle: %d .... FileName: %s\n", pHandleInfo[i].Handle, szFilePath);
CloseHandle(hTarget);
CloseHandle(hProcess);
continue;
}
if (_strnicmp(pString1, pszPath, lstrlen(pString1)) == 0)
{
++dwCount;
printf("Process:%d Handle: %d .... FileName: %s\n", pHandleInfo[i].ProcessId, pHandleInfo[i].Handle, szFilePath);
if (_strnicmp(pString2, "/c", 2) == 0)
{
BOOL fOk = DuplicateHandle(hProcess,
(HANDLE)pHandleInfo[i].Handle,
GetCurrentProcess(),
NULL,
0,
FALSE,
DUPLICATE_CLOSE_SOURCE);
if (fOk)
printf("Close Files Handle....Success\n");
else
printf("Close Files Handle....Failure\n");
}
}
CloseHandle(hTarget);
CloseHandle(hProcess);
}
}
HeapFree(g_hProcessHeap, 0, pvoid_HandleInfo);
if (dwCount == 0)
{
printf("Not found File: %s \n", pString1);
}
return 0;
}
int main(int argc, char *argv[])
{
if (argc < 2 ||
lstrcmpi(argv[1], "/?") == 0 ||
lstrcmpi(argv[1], "-?") == 0 ||
lstrcmpi(argv[1], "-h") == 0 ||
lstrcmpi(argv[1], "/help") == 0 ||
lstrcmpi(argv[1], "-help") == 0)
{
//ShowHelp(argv[0]);
exit(0);
}
EnableDebugPrivilge("SeDebugPrivilege", TRUE);
if (argc < 3)
{
printf("参数不正确!\n");
//ShowHelp(argv[0]);
exit(0);
}
if (lstrcmpi(argv[1], "/f") == 0)
{
Process(-1, argv[2], argv[1]);
return 0;
}
//
// if argv[3] is absolute path, operation will failed.
// but i don't want to solve this problem.
// 风泽 take responsibility for this bug,
// HA HA HA....
//
if (lstrcmpi(argv[1], "/c") == 0)
{
int dwProcessId = atoi(argv[2]);
if (dwProcessId > 0xFFFF ||
dwProcessId < 4)
{
printf("参数不正确!\n");
//ShowHelp(argv[0]);
exit(0);
}
if (!GetProcessNameById(dwProcessId))
{
printf("Not found process : %d\n\n", dwProcessId);
exit(0);
}
printf("Process Name: %s \n\n", g_szProcessName);
Process(dwProcessId, argv[3], argv[1]);
return 0;
}
if (lstrcmpi(argv[1], "/l") == 0)
{
int dwProcessId = atoi(argv[2]);
if (dwProcessId > 0xFFFF ||
argc > 3)
{
printf("参数不正确!\n");
//ShowHelp(argv[0]);
exit(0);
}
if (!GetProcessNameById(dwProcessId))
{
printf("Not found process : %d\n\n", dwProcessId);
exit(0);
}
printf("process name: %s \n\n", g_szProcessName);
Process(dwProcessId, NULL, argv[1]);
return 0;
}
if (lstrcmpi(argv[1], "/p") == 0)
{
int dwProcessId = atoi(argv[2]);
if (dwProcessId > 0xFFFF ||
argc < 3)
{
printf("参数不正确!\n");
//ShowHelp(argv[0]);
exit(0);
}
if (!GetProcessNameById(dwProcessId))
{
printf("Not found process : %d\n\n", dwProcessId);
exit(0);
}
printf("Process Name: %s \n\n", g_szProcessName);
if (ProtectFile(argv[3], dwProcessId))
{
printf("\n...Success!\n");
}
return 0;
}
}
2008-7-7 12:56, 下载次数: 1568
nevergone提供的完整逆向