Windows核心编程笔记之进程
- 改变进程基址,获取进程基址
#include <Windows.h>
#include <iostream>
#include <strsafe.h>
#include <STDLIB.H>
using namespace std;
#pragma comment(linker, "/BASE:0x400000") // 改变进程加载机地址
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WCHAR RouteBuffer[60] = { 0 };
DWORD res = GetModuleFileName(NULL, RouteBuffer, sizeof(RouteBuffer)); // 获取当前程序的全路径
WCHAR AfterVersion[130] = { 0 };
HMODULE EBAddress = GetModuleHandle(TEXT("NpCxyFW.exe")); // 获取当前进程的句柄 / 基址
StringCchPrintf(AfterVersion, sizeof(AfterVersion) / 2,
TEXT("程序全路径: %s\nhInstance获取到的程序基址: %x \nGetModuleHandle获取到的程序基址: %x"),
RouteBuffer, hInstance, EBAddress
);
INT Box_1 = MessageBox(NULL, AfterVersion, TEXT("测试"), MB_OKCANCEL);
return 0;
}
- 通过 GetCommandLine() 获取命令行参数
#include <Windows.h>
#include <iostream>
#include <strsafe.h>
using namespace std;
int main(int argc, char *argv[])
{
// 通过 GetCommandLine 获取命令行参数
INT CmdCount = NULL;
PWSTR *CmdLine = CommandLineToArgvW(GetCommandLine(), &CmdCount);
for (size_t i = 1; i < CmdCount; i++)
{
WCHAR *BeforeConversion = CmdLine[i]; CHAR AfterConversion[20] = { 0 };
// 将宽字节字符转换为多字节字符
int res = WideCharToMultiByte(CP_UTF8, NULL, BeforeConversion, -1, AfterConversion, sizeof(AfterConversion), NULL, NULL);
cout << "参数 " << i << ": "<< AfterConversion << endl;
}
return 0;
}
- 显示进程环境块
#include <Windows.h>
#include <iostream>
#include <wcschr.h>
#include <strsafe.h>
using namespace std;
int main(int argc, char *argv[])
{
PTSTR PEnvBlock = GetEnvironmentStrings(); // 获取进程环境块,也可以使用 int main(TCHAR *env[]) 的方式获取
TCHAR SzName[MAX_PATH]; TCHAR SzValue[MAX_PATH];
PTSTR PszCurrent = PEnvBlock;
HRESULT hr = S_OK; PCTSTR PszPos = NULL; int current = 0;
while (PszCurrent != NULL) {
if (*PszCurrent != TEXT('=')) { // 若第一个字符不是 '='
PszPos = _tcschr(PszCurrent, TEXT('=')); PszPos++; // 查找 '=' 在字符串中的位置
size_t cbNameLength = (size_t)PszPos - (size_t)PszCurrent - sizeof(TCHAR); // 获取 Name 字段的长度
hr = StringCbCopyN(SzName, MAX_PATH, PszCurrent, cbNameLength); // 将 Name 字段拷贝到 szName 中
if (FAILED(hr)) break;
hr = StringCchCopyN(SzValue, MAX_PATH, PszPos, _tcslen(PszPos) + 1); // 将 '=' 字符之后的内容拷贝至 szValue 中
if (SUCCEEDED(hr))
{
_tprintf(TEXT("[%u] %s=%s\r\n"), current, SzName, SzValue); // 成功便打印出信息
}
else
{
if (hr == STRSAFE_E_INSUFFICIENT_BUFFER) // 错误处理,STRSAFE_E_INSUFFICIENT_BUFFER 缓冲区空间不足
_tprintf(TEXT("[%u] %s=%s...\r\n"), current, SzName, SzValue);
else
_tprintf(TEXT("[%u] %s=???\r\n"), current, SzName); break;
}
}
else {
_tprintf(TEXT("[%u] %s\r\n"), current, PszCurrent); // 若一开始就为 '=' 字符,就直接打印出字符串的内容
}
current++; // 环境变量的个数加 1
while (*PszCurrent != TEXT('\0')) PszCurrent++; // 移动到字符串的结尾
PszCurrent++; // 跳过 '\0'
if (*PszCurrent == TEXT('\0')) break; // 检查它是否不是最后一个字符串
};
FreeEnvironmentStrings(PEnvBlock); //释放空间
return 0;
}
- 获得某个环境变量
#include <Windows.h>
#include <iostream>
#include <strsafe.h>
#include <stdio.h>
using namespace std;
int main(TCHAR *env[])
{
PWSTR lpBuffer = NULL;
DWORD Size = GetEnvironmentVariable(TEXT("PATH"), lpBuffer, 0); // 首先判断是否存在 PATH 环境变量
if (Size != 0)
{
DWORD BufferSize = Size * sizeof(TCHAR);
lpBuffer = (PWSTR)malloc(BufferSize); // 存在即分配缓冲区空间
GetEnvironmentVariable(TEXT("PATH"), lpBuffer, BufferSize);
printf("%ls", lpBuffer); // 打印 PATH 环境变量的信息
}
return 0;
}
- 获取当前目录
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <versionhelpers.h>
using namespace std;
BOOL CompareOS(INT dwMajorVersion, INT dwMinorVersion);
int main(TCHAR *env[])
{
// 获取当前目录方法 1
TCHAR Buffer_1[MAX_PATH] = { 0 };
DWORD DirLength = GetCurrentDirectory(MAX_PATH, Buffer_1);
printf("目录: %ls\n", Buffer_1);
// 获取当前目录方法 2
TCHAR Buffer_2[MAX_PATH];
DWORD PathLength = GetFullPathName(TEXT("C:"), MAX_PATH, Buffer_2, NULL);
printf("目录: %ls\n", Buffer_2);
return 0;
}
- 判断系统版本号的两种方法
VOID JudgeOS() // 通过 VerifyVersionInfo 比较判断,准确度一般
{
if (!CompareOS(10, 0))
if (!CompareOS(6, 3))
if (!CompareOS(6, 2))
if (!CompareOS(6, 1))
if (!CompareOS(6, 0))
if (!CompareOS(5, 2))
if (!CompareOS(5, 1))
if (!CompareOS(5, 0))
cout << "未知的操作系统版本" << endl;
else
cout << "版本在 Window2000 以上" << endl;
else
cout << "版本在 Windows XP 以上" << endl;
else
cout << "版本在 Windows XP Professional x64 Edition 以上" << endl;
else
cout << "版本在 Windows Vista 或者 Windows Server 2008 以上" << endl;
else
cout << "版本在 Windows 7 或者 Windows Server 2008 R2 以上" << endl;
else
cout << "版本在 Windows 8 或者 Windows Server 2012 以上" << endl;
else
cout << "版本在 Windows 8.1 或者 Windows Server 2012 R2 以上" << endl;
else
cout << "版本在 Windows Server 2016 或者 Windows 10 以上" << endl;
}
BOOL CompareOS(INT MajorVersion, INT MinorVersion)
{
OSVERSIONINFOEX OSinfo = { 0 };
OSinfo.dwOSVersionInfoSize = sizeof(OSinfo);
OSinfo.dwMajorVersion = MajorVersion; OSinfo.dwMinorVersion = MinorVersion; // 设置比较操作系统版本的区间组合
DWORDLONG dwlConditionMask = 0; // 设置用于比较操作系统的宏
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
BOOL Res = VerifyVersionInfo(&OSinfo, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); // 第二个参数为比较位,支持 or 操作
return Res; // 函数成功返回非 0 值
}
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <versionhelpers.h>
using namespace std;
// 利用官方的便捷函数进行操作系统的判别
INT JudgeOS();
int main(TCHAR *env[])
{
JudgeOS(); // 打印操作系统版本的信息
return 0;
}
INT JudgeOS()
{
if (IsWindowsServer())
cout << "操作系统是服务器" << endl;
else
if (!IsWindows10OrGreater())
if (!IsWindows8OrGreater())
if (!IsWindows7SP1OrGreater())
if (!IsWindows7OrGreater())
if (!IsWindowsVistaSP2OrGreater())
if (!IsWindowsVistaSP1OrGreater())
if (!IsWindowsVistaOrGreater())
if (!IsWindowsXPSP3OrGreater())
if (!IsWindowsXPSP2OrGreater())
if (!IsWindowsXPSP1OrGreater())
if (!IsWindowsXPOrGreater())
cout << "未知的操作系统版本" << endl;
else
cout << "当前操作系统版本是否与Windows XP版本匹配或大于Windows XP版本 " << endl;
else
cout << "当前操作系统版本是否与Windows XP Service Pack 1(SP1)版本匹配或大于" << endl;
else
cout << "当前操作系统版本是否与Windows XP Service Pack 2(SP2)版本匹配或大于" << endl;
else
cout << "当前操作系统版本是否与Windows XP Service Pack 3(SP3)版本匹配或大于" << endl;
else
cout << "当前操作系统版本是否与Windows Vista版本匹配或大于Windows Vista版本" << endl;
else
cout << "当前操作系统版本是否与Windows Vista Service Pack 1(SP1)版本匹配或大于" << endl;
else
cout << "当前操作系统版本是否与Windows Vista Service Pack 2(SP2)版本匹配或大于" << endl;
else
cout << "当前操作系统版本是否与Windows 7版本匹配或大于Windows 7版本" << endl;
else
cout << "当前操作系统版本是否与Windows 7 Service Pack 1(SP1)版本匹配或大于" << endl;
else
cout << "当前操作系统版本是否与Windows 8版本匹配或大于Windows 8版本" << endl;
else
cout << "指示当前操作系统版本是否与Windows 10版本匹配或大于Windows 10版本" << endl;
return 0;
}
- 进程创建
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <versionhelpers.h>
using namespace std;
int main(TCHAR *env[])
{
DWORD ExitCode = NULL;
// 创建线程和进程的安全结构体
SECURITY_ATTRIBUTES ProcessSec = { 0 }; SECURITY_ATTRIBUTES ThreadSec = { 0 };
ProcessSec.nLength = sizeof(ProcessSec); ThreadSec.nLength = sizeof(ThreadSec);
ProcessSec.bInheritHandle = TRUE; ThreadSec.bInheritHandle = TRUE; // 指定线程和进程为可以继承
STARTUPINFO StartInfo = { sizeof(STARTUPINFO) };
StartInfo.cb = sizeof(StartInfo); // STARTUPINFO 结构体用于新进程窗口设置
StartInfo.dwFlags = STARTF_USEPOSITION;
StartInfo.dwX = 400; StartInfo.dwY = 400; // 防止窗口重叠
PROCESS_INFORMATION ProcessInfo = { 0 }; // 返回进程信息的结构体
// 创建进程打开 cmd.exe 执行模块
TCHAR CmdLine[] = L"cmd.exe";
BOOL res = CreateProcess(NULL, CmdLine, &ProcessSec, &ThreadSec, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &StartInfo, &ProcessInfo); // CREATE_NEW_CONSOLE 用于创建一个新的控制台窗口
cout << "创建的新进程 ID: " << ProcessInfo.dwProcessId << endl; // ProcessInfo 结构体包含子进程和线程的 ID
cout << "创建的新线程 ID: " << ProcessInfo.dwThreadId << endl;
WaitForSingleObject(ProcessInfo.hThread, INFINITE); // 等待线程执行完毕
CloseHandle(ProcessInfo.hThread); // ProcessInfo 结构体包含子进程和线程的句柄
WaitForSingleObject(ProcessInfo.hProcess, INFINITE); // 等待进程执行完毕
GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode); // 获取进程退出代码
cout << ExitCode << endl;
CloseHandle(ProcessInfo.hProcess); // 关闭进程句柄
return 0;
}
- 手动提升程序权限
#include <Windows.h>
#include <iostream>
#include <strsafe.h>
using namespace std;
void ErrorExit(LPTSTR lpszFunction, DWORD LastError);
int main(int argc, char *argv[], TCHAR *env[])
{
SHELLEXECUTEINFOW ExeInfo = { sizeof(ExeInfo) }; // 初始化结构体
ExeInfo.lpVerb = TEXT("runas"); ExeInfo.lpFile = TEXT("cmd.exe"); ExeInfo.nShow = SW_SHOWNORMAL; // 设置操作的文件
if (!ShellExecuteEx(&ExeInfo))
{
DWORD LastError = GetLastError(); // 获取权限失败,保存错误代码
TCHAR ErrString[10] = L"错误代码";
ErrorExit(ErrString, LastError); // 调用 ErrorExit 函数打印详细信息
}
else
{
cout << "调用成功" << endl;
}
return 0;
}
void ErrorExit(LPTSTR lpszFunction, DWORD LastError)
{
// 检索最后错误码的系统错误消息
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = LastError; // 模拟错误代码定义为 123
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | // 函数自动使用 LocalAlloc 函数,来为 lpBuffer 分配内存
FORMAT_MESSAGE_FROM_SYSTEM | // 定义可以使用 GetLastError 的返回值赋给 dw
FORMAT_MESSAGE_IGNORE_INSERTS, // 这个标志表示 Arguments 参数将被忽略
NULL, // 消息所在位置,这个参数类型,根据dwFlags标志来设定
dw, // 消息索引,如果 lpSource 是一个字符串,那么这个参数被忽略
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 设置为本地默认语言
(LPTSTR)&lpMsgBuf, // 接受消息字符串的内存块
0, // 内存大小
NULL); // 消息中的参数
// 显示错误消息并退出进程
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, // 将内存初始化为 0
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); // 为字符串指针区域申请足够大小的内存
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), // 目标缓冲区和目标缓冲区的大小
TEXT("%s %d 的含义是: %s"), // 格式字符串
lpszFunction, // 参数1
dw, // 参数2
lpMsgBuf); // 参数3
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf); // 释放空间
LocalFree(lpDisplayBuf);
ExitProcess(dw); // 关闭进程
}
- 查看是否为上下文管理员权限
#include <Windows.h>
#include <iostream>
#include <shlobj.h>
#include <strsafe.h>
using namespace std;
VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode);
DWORD WINAPI GetProcessElevation(TOKEN_ELEVATION_TYPE *pElevationType, BOOL* lsAdmin);
int main(INT argc, CHAR *argv[], TCHAR *env[])
{
// pElevationType 为令牌的上下文权限类型,IsAdmin 标识是否为管理员权限
TOKEN_ELEVATION_TYPE pElevationType; BOOL IsAdmin;
if (GetProcessElevation(&pElevationType, &IsAdmin))
{
switch (pElevationType)
{
case TokenElevationTypeDefault:
cout << "[-] 进程以默认用户运行,或者UAC被禁用" << endl; break;
case TokenElevationTypeFull:
cout << "[*] 进程的权限被成功提升,而且令牌没有被筛选过" << endl; break;
case TokenElevationTypeLimited:
cout << "[*] 进程使用和一个筛选过的令牌对应的受限的权限运行" << endl; break;
}
if (IsAdmin) cout << "[*] 进程为管理员权限" << endl;
else cout << "[-] 进程为普通权限" << endl;
}
else
{
DWORD ErrorCode = GetProcessElevation(&pElevationType, &IsAdmin);
ErrorCodeTransformation(ErrorCode);// 打印错误信息
}
return 0;
}
DWORD WINAPI GetProcessElevation(TOKEN_ELEVATION_TYPE *pElevationType, BOOL* pIsAdmin)
{
HANDLE hToken = NULL; DWORD dwSize; DWORD ErrorCode = NULL;
// OpenProcessToken 用于打开当前进程的令牌,hToken 为令牌的句柄
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
// 调用失败返回错误代码
ErrorCode = GetLastError();
return (ErrorCode);
}
BOOL bResult = FALSE;
// GetTokenInformation 用于获取当前令牌是什么令牌,令牌种类储存在 pElevationType 中
if (GetTokenInformation(hToken, TokenElevationType, pElevationType, sizeof(TOKEN_ELEVATION_TYPE), &dwSize))
{
BYTE adminSID[SECURITY_MAX_SID_SIZE];
dwSize = sizeof(adminSID);
// CreateWellKnownSid 定义一个描述符为 WinBuiltinAccessControlAssistanceOperatorsSid 的别名 SID
// adminSID 中储存的是新的 SID
CreateWellKnownSid(WinBuiltinAccessControlAssistanceOperatorsSid, NULL, &adminSID, &dwSize);
// 如果当前进程的令牌被筛选过
if (*pElevationType == TokenElevationTypeLimited)
{
HANDLE hUnfilteredToken = NULL;
// 获取当前进程未筛选过令牌的句柄,句柄保存在 hUnfilteredToken
GetTokenInformation(hToken, TokenLinkedToken, (VOID *)&hUnfilteredToken, sizeof(HANDLE), &dwSize);
// CheckTokenMembership 用于将模拟令牌和创建的安全描述符做比较,判断令牌的上下文访问权限是否为管理员
if (CheckTokenMembership(hUnfilteredToken, &adminSID, pIsAdmin)) bResult = TRUE;
CloseHandle(hUnfilteredToken);
}
else
{ // IsUserAnAdmin 函数是 CheckTokenMembership 的包装函数
// 建议直接调用该函数以确定管理员组状态,而不是调用 IsUserAnAdmin
*pIsAdmin = IsUserAnAdmin();
bResult = TRUE;
}
}
CloseHandle(hToken);
return (bResult);
}
// 如果返回错误,可调用此函数打印详细错误信息
VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode)
{
LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = ErrorCode;
// 将错误代码转换为错误信息
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL
);
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
// 格式化打印
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("错误代码 %d : %s"), dw, lpMsgBuf);
// 输出错误信息
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
// 释放资源
LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw);
}
- 获取系统进程列表,操作进程句柄
#include <Windows.h>
#include <iostream>
#include <shlobj.h>
#include <strsafe.h>
#include <stdio.h>
#include <tlhelp32.h>
using namespace std;
VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode);
DWORD WINAPI ProcessInfo(VOID);
DWORD WINAPI ProcessHandle(DWORD ProcessID);
int main(INT argc, CHAR *argv[], TCHAR *env[])
{
DWORD ErrorCode = ProcessInfo();
// 打印详细的错误信息
ErrorCodeTransformation(ErrorCode);
return 0;
}
DWORD WINAPI ProcessInfo(VOID)
{
// ErrorCode 用于统计错误信息,ProcessCount 用于统计进程数
DWORD ErrorCode = NULL; INT ProcessCount = 0;
// 使用 CreateToolhelp32Snapshot 获取当前所有的进程快照
HANDLE ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_INHERIT | TH32CS_SNAPALL, 0);
if (ProcessSnapshot == INVALID_HANDLE_VALUE)
{
// 调用错误返回错误代码,以便查出详细的错误信息
ErrorCode = GetLastError();
return (ErrorCode);
}
PROCESSENTRY32W ProcessInfo; ProcessInfo.dwSize = sizeof(ProcessInfo); // 必须初始化结构体大小
// Process32First 用于获取第一个进程,返回进程信息至 ProcessInfo 结构体
BOOL DisResult = Process32First(ProcessSnapshot, &ProcessInfo);
if (!DisResult)
{
// 调用错误返回错误代码,以便查出详细的错误信息
ErrorCode = GetLastError();
return (ErrorCode);
}
// 进程数量加一
ProcessCount++;
cout << " 显示进程 ID: " << ProcessInfo.th32ProcessID << endl;
while (DisResult)
{
ProcessCount++;
// 获取下一个进程的详细信息
DisResult = Process32Next(ProcessSnapshot, &ProcessInfo);
// 打印进程 ID
cout << " ID: " << ProcessInfo.th32ProcessID;
// 有关句柄的详细操作
ProcessHandle(ProcessInfo.th32ProcessID);
// 打印进程名称
printf(" 进程名: %ls\n ", ProcessInfo.szExeFile);
}
return 0;
}
DWORD WINAPI ProcessHandle(DWORD ProcessID)
{
DWORD ErrorCode = NULL;
// OpenProcess 将进程 ID 转换进程句柄,方便对进程进行操作
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, TRUE, ProcessID);
if (!ProcessHandle)
{
// 调用错误返回错误代码,以便查出详细的错误信息
ErrorCode = GetLastError();
if (ErrorCode == 5) cout << " 访问状态: 拒绝访问 ";
return (ErrorCode);
}
else
{
// 操作进程句柄....
}
// 关闭句柄
CloseHandle(ProcessHandle);
return TRUE;
}
// 如果返回错误,可调用此函数打印详细错误信息
VOID WINAPI ErrorCodeTransformation(DWORD ErrorCode)
{
LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = ErrorCode;
// 将错误代码转换为错误信息
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL
);
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf), TEXT("错误代码 %d : %s"), dw, lpMsgBuf);
// 弹窗显示错误信息
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw);
}
Windows核心编程笔记之进程的更多相关文章
- C++windows内核编程笔记day13 进程、线程与信号量
Windows进程 进程是一个容器,包括程序运行须要的代码.数据.资源等信息, windows进程的特点: 每一个进程都有自己的ID号 每一个进程都有自己的地址空间.进程之间无法訪问对方的地址空间. ...
- Windows核心编程笔记之作业
创建作业,并加以限制 HANDLE WINAPI CreateJob() { BOOL IsInJob = FALSE; DWORD ErrorCode = NULL; // 不能将已经在作业中的进程 ...
- Windows核心编程笔记之内核对象
0x01 子进程继承父进程内核对象句柄 父进程 #include <Windows.h> #include <iostream> #include <strsafe.h& ...
- Windows核心编程笔记之错误处理
0x01 GetLastError() 函数用于获取上一个操作的错误代码 #include <Windows.h> #include <iostream> using name ...
- Windows核心编程笔记之处理字符串
0x01 ANSI 和宽字符定义 // ANSI 字符定义 CHAR varChar_1 = 'a'; // #typedef char CHAR CHAR varChar_2[] = "A ...
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 【转】《windows核心编程》读书笔记
这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...
- Windows核心编程:第4章 进程
Github https://github.com/gongluck/Windows-Core-Program.git //第4章 进程.cpp: 定义应用程序的入口点. // #include &q ...
随机推荐
- Windows下用户手册
(1)net user(查看系统用户) (2)net user 用户名(查看具体某个系统用户详细信息) (3)net user 用户名 密码 /add(在本地组成员创建新用户,此时为Users组) ...
- 如何使用excel制作查分系统
在工作学习中,我们经常会遇到使用excel制作查分系统这样的问题.培根说过:读书足以恬情,足以博采,足以长才.因此,面对使用excel制作查分系统我们应该有努力探索的精神.书到用时方恨少,事非经过不知 ...
- 过多if - else 的问题, 以及策略模式 + 反射解决方法
策略模式解决if - else 的代码 业务场景: 外包企业的审批人需要审批打卡的场景: 审批人分为多种不同的级别,多种级别中具有方式相同但是内容不同的操作:审批. 原来场景: 有前端传来审批人参数, ...
- CF1149C Tree Generator™
一.题目 点此看题 二.解法 话说老师给的课件是错的啊,把我坑了好久,我手玩样例才玩出来,最后只能去看洛谷题解了. 本题是树是用一个括号序列给出的,你要知道的是:( 代表递归下去到一个新节点,) 表示 ...
- Python:垃圾回收
有很多不同的方法来实现垃圾回收,例如跟踪,引用计数,转义分析,时间戳和心跳信号等.不同的语言依赖于不同的垃圾回收实现,例如,有些将其与编译器和运行时系统集成在一起.而其他语言则可能需要事后设置,甚至可 ...
- POJ - 1163 The Triangle 【动态规划】
一.题目 The Triangle 二.分析 动态规划入门题. 状态转移方程$$DP[i][j] = A[i][j] + max(DP[i-1][j], DP[i][j])$$ 三.AC代码 1 #i ...
- Python基础之异常定义
技术背景 在各类python的项目中,总会涉及到项目自身相关的一些约束条件.这些约束条件体现在,当用户输入的参数或者文件不符合项目要求时,就拒绝这个参数的输入并且播报出来,提醒用户自行修改,而这一过程 ...
- PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642
PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642 题目描述: People in Mars represent the c ...
- tasker支持的shell 命令大全
参考 http://www.notenoughtech.com/tasker/tasker-run-shell-commands/ 罗列所有系统配置项 settings list system s ...
- shell分支与循环结构
1. 条件选择 1.1 条件判断分支介绍 格式 if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMM ...