文件相关:
创建或打开文件:
HANDLE CreateFile(
LPCSTR lpFileName, //欲打开或创建的文件名,也可以是设备对象之类的被视为文件的相关对象
DWORD dwDesiredAccess, //对文件的访问模式,只读,只写,还可以进行位或同时指定两种模式
DWORD dwShareMode, //打开文件的共享模式,文件是否允许其他进程进行操作,如果可以,可以指定操作的模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //表示安全属性可以指定返回的文件句柄是否可以被子进程继承,如果为NULL,表示无法被继承,否则需要将参数指向一个SECURITY_ATTRIBUTES的结构体,通常设为NULL
DWORD dwCreationDisposition, //在创建或打开的文件存在或不存在的时候该函数的处理方式
DWORD dwFlagsAndAttributes, //该参数用来指定新建文件的属性和对文件操作的方式
HANDLE hTemplateFile //文件模块句柄,系统会复制该文件模板的所有属性到当前创建的文件中
);
//该函数若执行成功,则返回文件句柄,若失败则返回INVALID_HANDLE_VALUE。具体失败的原因可以通过GetLastError()函数来得到,该函数即可以打开文件也可以创建文件,创建或打开文件之后要用CloseHandle()将文件句柄关闭
eg: CreateFile(szTraget,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTES_NORMAL,NULL);
删除文件:
BOOL DeleteFile(
LPCSTR lpFileName //表示要删除的文件的文件名
);
读取文件内容:
BOOL ReadFile(
HANDLE hFile, //文件句柄,通常是CreateFile(返回的句柄)
LPVOID lpBuffer, //指向一个缓冲区,函数会将从文件中读出的数据保存在该缓冲区中
DWORD nNumberOfBytesToRead, //要求读入的字节数,通常情况下是缓冲区的大小
LPDWORD lpNumberOfBytesRead, //指向一个DWORD类型的变量,用于返回实际读入的字节数
LPOVERLAPPED lpOverlapped //一般设置位NULL
);
写入文件内容:
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
//和ReadFile()函数的参数意义基本相同,所不同的是第二个参数,第二个参数仍指向同一个缓冲区,WriteFile()函数会将该缓冲区的内容进行写入。当用WriteFile()函数写文件时,写入的数据通常被Windows暂时保存在内部的高速缓存中,操作系统会定期进行盘写入,从而避免进行I/O操作影响执行效率。为了保证数据即时写入可以使用
FlushFileBuffers(
HANDLE hFile //handle to file
)
//该函数会将指定文件句柄的缓冲区进行清空,使得Windows将缓冲区中的文件写入磁盘。该函数只有一个参数,即文件句柄。该文件句柄与ReadFile()和WriteFile()所使用的文件句柄相同
定位到文件的某个位置
DWORD SetFilePointer(
HANDLE hFile, //进行文件操作时的文件句柄
LONG lDistanceToMove, //指定要移动文件指针的距离
PLONG lpDistanceToMoveHigh, //一个指向LONG型的指针,移动距离的高32位,一般为NULL
DWORD dwMoveMethod //指针移动的起始位置。可以从文件开始位置进行移动,可以从当前文件位置开始移动,也可以从文件的末尾开始移动
);
获取本地所有逻辑驱动器
DWORD GetLogicalDriveStrings(
DWORD nBufferLength, //表示lpBuffer的长度
LPWSTR lpBuffer //表示接受本地逻辑驱动器名的缓冲区
);
获取驱动器类型
UINT GetDriveType(
LPCSTR lpRootPathName //驱动器名
);
创建目录
BOOL CreateDirectory(
LPCSTR lpPathName, //创建目录的目录名称
LPSECURITY_ATTRIBUTES lpSecurityAttributes //安全属性,一般设置为NULL
);
移除目录
BOOL RemoveDirectory(
LPCSTR lpPathName //指定要移除目录的目录名
);
注册表相关:
基础知识:注册表是Windows系统管理和维护的配置较为复杂的信息数据库,它以树状形式存储信息,不同版本的Windows系统,其结构基本相同。由于各种软件为了满足自身的不同需求,对注册表中的信息进行读写,导致注册表中存在大量的冗余数据,因此有人戏称注册表是一个数据杂乱的“垃圾场”
注册表主要有这几项信息:根键、子键、键值项!键值项又包含:值名称,值类型和值
API:
打开注册表
LSTATUS RegOpenKeyEx(
HKEY hKey, //指定一个父键句柄
LPCSTR lpSubKey, //指向一个字符串,用来表示要打开的子健名称
DWORD ulOptions, //系统保留,必须指定为0值
REGSAM samDesired, //打开注册表的存取权限,为了方便对注册表的操作,通常使用KEY_ALL_ACCESS即可
PHKEY phkResult //指向一个双子变量,用来接收打开的子键句柄
);
//如果函数执行成功,则返回ERROR_SUCCESS,并且在phkResult中保存返回打开子键的句柄
//所谓的打开注册表,就是打开注册表的某一个子键,然后进行操作
关闭注册表
LONG RegCloseKey{
HKEY hKey //是RegOpenKeyEx()的最后一个参数,即被打开的注册表句柄。
}
创建子键
LSTATUS RegCreateKeyEx(
HKEY hKey, //用来指定父键句柄
LPCSTR lpSubKey, //指向一个字符串,用来表示要创建的子键名称
DWORD Reserved, //系统保留,必须指定为0值
LPSTR lpClass, //子键类名,一般设置为NULL值
DWORD dwOptions, //创建子键时的选项,通常情况下使用REG_OPTION_NON_VOLATILE宏,表示创建的子键被创建到注册表文件中,而不是内存中
REGSAM samDesired, //打开注册表的存取权限,为了方便对注册表的操作,通常使用KEY_ALL_ACCESS即可
const LPSECURITY_ATTRIBUTES lpSecurityAttributes, //该参数指向一个SECURITY_ATTRIBUTES结构体用来指定键句柄的安全属性,这里一般使用NULL
PHKEY phkResult, //指向一个双子变量,用来接收打开的子键句柄
LPDWORD lpdwDisposition //一般设置为NULL
);
//如果函数执行成功,则返回ERROR_SUCCESS,并且在phkResult中保存返回创建子键的句柄。当需要创建的子键已经存在的时候,该函数起到与RegOpenKeyEx()函数同样的作用,那么打开系统注册表也可以使用RegCreateKeyEx()函数进行代替。不过该函数的参数比RegOpenKeyEx()多,所以不是很方便
删除子键
LSTATUS RegDeleteKey(
HKEY hKey, //父键句柄
LPCSTR lpSubKey //要删除的子键名称
);
读取键名称中的数据或者查询键名称的属性
LSTATUS RegQueryValueEx(
HKEY hKey, //用来指定要读取的键值项所处的子键句柄
LPCSTR lpValueName, //用来指定要读取的键值项的名称
LPDWORD lpReserved, //保留参数,必须为NULL
LPDWORD lpType, //接收返回的键值类型,如果不需要返回键值项类型,可以为NULL
LPBYTE lpData, //指向一个缓冲区,用来接收返回的键值数据
LPDWORD lpcbData //在调用该函数时,这个参数用来指定缓冲区的长度;当函数返回时,该变量保存缓冲区实际接受到的长度
);
写入键值项
LSTATUS RegSetValueEx(
HKEY hKey, //表示要写入键值项所处的子键句柄
LPCSTR lpValueName, //指向定义键值项名称的字符串
DWORD Reserved, //保留参数,必须为0
DWORD dwType, //指出要写入的键值数据的类型
const BYTE *lpData, //指向要写入键值数据的缓冲区
DWORD cbData //要写入键值数据的缓冲区长度
);
删除键值项
LONG RegDeleteValue{
HKEY hKey; //指定要删除的句柄
LOCTSTR lpValueName //被删除键值项的名称
}
子键枚举
LSTATUS RegEnumKeyEx(
HKEY hKey, //指定被枚举的键句柄
DWORD dwIndex, //指定需要返回信息的子键索引编号
LPSTR lpName, //用户接收返回子键名称的缓冲区
LPDWORD lpcchName, //调用函数前保存lpName指向缓冲区的长度,函数调用完成后,保存缓冲区实际接收到的数据长度
LPDWORD lpReserved, //保留参数,必须为NULL
LPSTR lpClass, // 一般为NULL
LPDWORD lpcchClass, //一般为NULL
PFILETIME lpftLastWriteTime //指向一个FILETIME的结构体,用于接收最后一次被写入的时间
);
键值枚举
LSTATUS RegEnumValue(
HKEY hKey, //指定被枚举的键句柄
DWORD dwIndex, //指定需要返回信息的键值索引编号
LPSTR lpValueName, //用户接收返回键值名称的缓冲区
LPDWORD lpcchValueName, //在调用函数前,保存lpValueName指向的缓冲区的长度,调用完成后,保存缓冲区实际接收到的数据长度
LPDWORD lpReserved, //保留参数,必须为NULL
LPDWORD lpType, //指向一个用于返回键值类型的双字变量
LPBYTE lpData, //用户接收返回值数据的缓冲区
LPDWORD lpcbData //在调用该函数前,该参数保存lpData指向缓冲区的长度,该函数调用完成后,该参数保存缓冲区实际收到的数据长度
);
服务相关
打开服务管理器
SC_HANDLE OpenSCManager(
LPCSTR lpMachineName, //指向想要打开服务控制管理的主机,本机则设置为NULL
LPCSTR lpDatabaseName, //指向目标主机SCM数据库名字的字符串
DWORD dwDesiredAccess //指定对SCM数据库的访问权限
);
//该函数调用成功,返回一个SCM句柄,否则返回NULL
//注:SCM是服务控制管理器的意思,他是系统服务的一个组成部分,跟开发的软件不是一个概念
关闭服务管理器
BOOL CloseServiceHandle{
SC_HANDLE_hSCObject
}
//该函数用来关闭由OpenSCManager()和OpenService()打开的句柄
服务的枚举
BOOL EnumServicesStatus(
SC_HANDLE hSCManager, //OpenSCMamager()函数返回的句柄
DWORD dwServiceType, //指定枚举的服务类型,也就是自定义函数的参数
DWORD dwServiceState, //枚举指定状态的服务
LPENUM_SERVICE_STATUSA lpServices, //指向ENUM_SERVICE_STATUS类型的指针
DWORD cbBufSize, //指定缓冲区的大小
LPDWORD pcbBytesNeeded, //返回实际使用的内存空间大小
LPDWORD lpServicesReturned, //返回枚举服务的个数
LPDWORD lpResumeHandle //返回枚举是否成功
);
//ENUM_SERVICE_STATUS结构体
typedef struct _ENUM_SERVICE_STATUSA {
LPSTR lpServiceName;
LPSTR lpDisplayName;
SERVICE_STATUS ServiceStatus;
} ENUM_SERVICE_STATUSA, *LPENUM_SERVICE_STATUSA;
//SERVICE_STATUS结构体
typedef struct _SERVICE_STATUS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;
打开服务
SC_HANDLE OpenService(
SC_HANDLE hSCManager, //指向由OpenSCManager()函数打开的服务句柄
LPCSTR lpServiceName, //指定要打开的服务的名称
DWORD dwDesiredAccess //对要打开服务的访问权限,为了方便可以用SC_MANAGER_ALL_ACCESS
);
启动服务
BOOL StartService(
SC_HANDLE hService, //指定要启动服务的句柄,该句柄由OpenService()返回
DWORD dwNumServiceArgs, //指定启动服务所需的参数个数
LPCSTR *lpServiceArgVectors //指定启动服务的参数
);
停止服务
BOOL ControlService(
SC_HANDLE hService, //指定一个由OpenService()打开的服务句柄
DWORD dwControl, //指定要发送的控制码
LPSERVICE_STATUS lpServiceStatus //返回服务的状态
);
//这个函数可以对服务进行多种控制操作,每种控制操作对应一种控制码,当要停止服务时,使用的控制码为SERVICE_CONTROL_STOP
进程线程相关
创建进程
BOOL CreateProcess(
LPCSTR lpApplicationName, //指定可执行文件的文件名
LPSTR lpCommandLine, //指定相传给命令行的参数
LPSECURITY_ATTRIBUTES lpProcessAttributes, //进程安全属性,通常为NULL。表示默认安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, //线程安全属性,通常为NULL,表示默认安全属性
BOOL bInheritHandles, //指定当前进程中的科技城句柄是否被新进程继承
DWORD dwCreationFlags, //指定新进程的优先级以及其他创建标志,该参数一般情况下可为0
LPVOID lpEnvironment, //指定新进程的环境变量,通常这里指定为NULL值
LPCSTR lpCurrentDirectory, //指定新进程使用的当前目录值
LPSTARTUPINFOA lpStartupInfo, //指向STATUPINFO结构体的指针,该结构体的定义如下:
LPPROCESS_INFORMATION lpProcessInformation //指向PROCESS_INFORMATION结构体的指针,该结构体用于返回新进程和主线程的相关信息,定义如下:
);
typedef struct _STARTUPINFOA {
DWORD cb;
LPSTR lpReserved;
LPSTR lpDesktop;
LPSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
得到窗口线程PID
DWORD GetWindowThreadProcessId(
HWND hWnd, //窗口句柄,代码中的窗口句柄是由FindWindow()函数获取的
LPDWORD lpdwProcessId //该参数是一个指向DWORD类型的指针,用户返回窗口句柄所对应的进程ID
);
通过进程ID得到进程句柄
HANDLE OpenProcess(
DWORD dwDesiredAccess, //打开进程欲获得的访问权限,该参数为了方便,可以始终为PROCESS_ALL_ACCESS
BOOL bInheritHandle, //指定获得的句柄是否可以被继承,,一般选择不继承,为FALSE
DWORD dwProcessId //指定想要打开的进程ID号,该进程ID号是由GetWindowThreadProcessID()所得的
);
通过进程句柄类结束进程
BOOL TerminateProcess(
HANDLE hProcess, //想要结束的进程句柄,该句柄由OpenProcess()函数得到
UINT uExitCode //进程的退出码,通常为0
);
进程枚举相关的函数
#include <Tlhelp32.h>
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags, //指明要建立快照的类型
DWORD th32ProcessID //根据dwFlags的参数的不同而不同,如果枚举的是系统中的进程或系统中的线程,该参数为NULL,如果枚举的是进程中加载的DLL的话,那么该进程参数是进程ID
);
//该函数返回一个快照的句柄,并提供给枚举函数使用
BOOL Process32First(
HANDLE hSnapshot, //该参数为CreateToolhelp32Snapshot()返回的句柄
LPPROCESSENTRY32 lppe //该参数为指向PROCESSENTRY32结构体的指针,该结构体的定义如下
);
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
CHAR szExeFile[MAX_PATH];
} PROCESSENTRY32;
//在使用该结构体时,要对结构体中的程序变量dwSize进行复制。该变量保存PROCESSENTRY32结构体的大小
BOOL Process32Next(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
//枚举进程中加载的DLL文件和枚举系统中得到线程都与以上两个函数类似,所不同的是使用FIRST和NEXT的第二个参数指向的结构体不同
//对于dll文件来说,指向的结构体如下
typedef struct tagMODULEENTRY32 {
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE *modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
char szModule[MAX_MODULE_NAME32 + 1];
char szExePath[MAX_PATH];
} MODULEENTRY32;
//对于系统中的线程来说,指向的结构体定义如下
typedef struct tagTHREADENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ThreadID;
DWORD th32OwnerProcessID;
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
} THREADENTRY32;
//有些权限不足的进程无法被枚举出来,进程的权限不够,解决方法是将进程的权限提升至"SeDebugPrivilege"
//调整进程权限的步骤如下
//1、使用OpenProcessToken()函数打开当前进程的访问令牌
//2、使用LookupPrivilegeValue()函数取得描述权限的LUID
//3、使用AdjustTokenPrivileges()函数调整访问令牌的权限
//调整权限的代码如下:
void CManagerProcessDlg::DebugPrivilege()
{
HANDLE hToken = NULL;
BOOL bRet = OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken);
if(bRet == TRUE)
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&TP,sizeof(tp),NULL,NULL);
CloseHandle(hToken);
}
}
暂停线程
DWORD SuspendThread( HANDLE hThread );
//该函数只有一个参数,是要暂停线程的句柄
获得线程句柄
HANDLE OpenThread(
DWORD dwDesiredAccess, //打开线程欲获得的访问权限,为了方便,可以始终为PROCESS_ALL_ACCESS
BOOL bInheritHandle, //指定获取的句柄是否可以继承,一般选择不继承,传FALSE
DWORD dwThreadId //线程ID
);
恢复暂停的线程
DWORD ResumeThread(
HANDLE hThread //线程句柄
);
多线程相关:
线程创建:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //指明创建线程的安全属性,为指向SCEURITY_ATTRIBUTES结构的指针,一般为NULL
SIZE_T dwStackSize, //指定线程使用的缺省的堆栈大小,如果为NULL,则与进程主线程栈相同
LPTHREAD_START_ROUTINE lpStartAddress, //指定线程函数,线程即从该函数的入口处开始运行,函数返回时意味着线程终止运行,该函数属于一个回调函数
__drv_aliasesMem LPVOID lpParameter, //该参数表示传递给线程函数的一个参数,可以是指向任意数据类型的指针
DWORD dwCreationFlags, //指明创建线程后的线程状态,需要立即执行设置为0,让线程处于暂停状态,那么设置为CREATE_SUSPENDED
LPDWORD lpThreadId //该参数用于返回新创建的线程ID
);
//如果函数创建成功,该函数返回线程的而句柄,否则返回NULL。线程的句柄需要通过CloseHandle()进行关闭,以便释放资源
主线程等待新线程的完成才执行
DWORD WaitForSingleObject(
HANDLE hHandle, //要等待的对象句柄
DWORD dwMilliseconds //指定等待超时的毫秒数,如果为0,则立即返回,如果为INFINITE,则表示一直等待线程函数的返回
);
#define INFINITE 0xFFFFFFFF
//如果函数失败,返回WAIT_FAILED;富国等待的对象编程激发状态,则返回WAIT_OBJECT_0。如果等待对象编程激发状态之前,等待时间结束了,将返回WAIT_TIMEOUT
如果需要等待多个线程完成状态的话,需要用到
DWORD WaitForMultipleObjects(
DWORD nCount, //用于指明想要让函数等待的线程的数量,这个值在1和MAXIMUM_WAIT_OBJECTS之间
const HANDLE *lpHandles, //指向等待线程句柄的数组指针
BOOL bWaitAll, //该参数表示是否等待全部线程的状态完成,如果设置为TRUE,则等待全部
DWORD dwMilliseconds //等待超时的毫秒数,如果为0,则立即返回,如果为INFINITE,则表示一直等待线程函数的返回
);
临界区相关的函数
void InitializeCritcalSection{
LPCRITICAL_SECTION lpCriticalSection
}
//初始化临界区对象
void EnterCritcalSection{
LPCRITICAL_SECTION lpCriticalSection
}
//进入临界区
void LeaveCritcalSection{
LPCRITICAL_SECTION lpCriticalSection
}
//离开临界区
void DeleteCritcalSection{
LPCRITICAL_SECTION lpCriticalSection
}
//删除临界区
//注:临界区对象只能用于多线程互斥
DLL相关
加载DLL文件
HMODULE LoadLibrary(
LPCSTR lpLibFileName //要加载的DLL的文件名。该函数调用成功,则返回一个模块句柄
);
得到进程地址
FARPROC GetProcAddress(
HMODULE hModule, //该参数是模块句柄,通常通过LoadLibrary()和GetModuleHandle()函数获得
LPCSTR lpProcName //指定要获得函数地址的函数名称
);
//函数调用成功,则返回lpProcName指向的函数名的函数地址
DLL远程注入
创建远程线程
HANDLE CreateRemoteThread(
HANDLE hProcess, //指定要创建线程的进程句柄,其他参数和CreateThread()相同
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
将欲加载的DLL文件完成路径写入目标进程中
BOOL WriteProcessMemory(
HANDLE hProcess, //指定进程的进程句柄
LPVOID lpBaseAddress, //指定写入目标进程内存的起始地址
LPCVOID lpBuffer, //写入目标进程内存的缓冲区起始地址
SIZE_T nSize, //指定写入目标内存中的缓冲区长度
SIZE_T *lpNumberOfBytesWritten //用于接收实际写入内容的长度
);
//该函数的功能是把lpBuffer中的内容写到进程句柄是hProcess进程的lpBaseAddress地址处,写入长度为nSize
//注:该函数功能非常强大,比如在破解方面,用该函数可以实现一个“内存补丁;在开发方面”,该函数可以用于修改目标进程中指定的值(比如游戏修改器可以修改游戏中的钱)
在目标进程中申请内存
LPVOID VirtualAllocEx(
HANDLE hProcess, //指定进程的进程句柄
LPVOID lpAddress, //指定在目标进程中申请内存的起始地址
SIZE_T dwSize, //在目标进程中申请内存的长度
DWORD flAllocationType, //指定申请内存的状态类型
DWORD flProtect //指定申请内存的属性
);
//该函数的返回值实在目标进程申请到的内存块的起始地址
DLL卸载
BOOL FreeLibrary(
HMODULE hLibModule //要卸载模块的句柄
);
1057



被折叠的 条评论
为什么被折叠?



