C++常用程序记录
C++常用程序记录
1.读取文件,替换指定字符串为另一字符串。
稍微改改,就可以变成替换指定字节数组了
朴实无华的操作,只能替换等长的内容
代码:
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
string oldStr = "helloworld";
string newStr = "xxhhaabbcc";
int length = oldStr.length();
unsigned char* oldBytes = (unsigned char*)oldStr.c_str();
unsigned char* newBytes = (unsigned char*)newStr.c_str();
string filename = "";
cout<<"请输入文件名"<<endl;
cin>>filename;
FILE* fp = fopen(filename.c_str(),"rb");
fseek(fp,0,SEEK_END);
int len = ftell(fp);
fseek(fp,0,SEEK_SET);
unsigned char data[len];
fread(data,1,len,fp);
fclose(fp);
int count = 0;
for(int i;i<len;i++)
{
if(!memcmp(data+i,oldBytes,length))//0为相等
{
memcpy(data+i,newBytes,length);
i+=length;
count++;
}
}
cout<<"一共匹配替换 "<<count<<"次"<<endl;
cout<<"请输入保存文件名"<<endl;
cin>>filename;
fp = fopen(filename.c_str(),"wb");
fwrite(data,1,len,fp);
fclose(fp);
}
后续有用到其他的,再更新吧。
2. _ReturnAddress()
此函数返回当前所在函数返回后执行的下一条指令。
通俗一点,就是返回进入当前函数后的栈顶数据。
代码:(来源于网上)
// compiler_intrinsics__ReturnAddress.cpp
#include <stdio.h>
#include <windows.h>
#include <intrin.h>
#pragma intrinsic(_ReturnAddress)
__declspec(noinline) ULONG_PTR caller(VOID) { return (ULONG_PTR)_ReturnAddress(); }
__declspec(noinline)
void noinline_func(void)
{
void *callerAddress = _ReturnAddress();
printf("Return address from %s: %p\n", __FUNCTION__, callerAddress);
}
__forceinline
void inline_func(void)//感觉是强制内联到main函数的意思吧,没用过,不太懂。
{
void *callerAddress = _ReturnAddress();
printf("Return address from %s: %p\n", __FUNCTION__, callerAddress);
}
int main(void)
{
noinline_func();
ULONG_PTR uiLibraryAddress = caller();//这里应该输出第一个nop的地址
__asm
{
nop
nop
nop
nop
}
inline_func();//此条和下一条应该是一样的结果
printf("Return address from %s: %p\n", __FUNCTION__, _ReturnAddress());
printf("noinlineaddr = %p, inline_funcaddr = %p,uiLibraryAddress = %p \n", noinline_func, inline_func, uiLibraryAddress);
system("pause");
return 0;
}
这是某一次的输出结果,因为vs2015默认开启了随机基址。
不过不影响什么,偏移量都是固定的。
理解的好方法就是用OD或者x32dbg调试一下。
003212B3,这是等下inline函数和main里面调用_ReturnAddress(),输出的地址
其他的inline和noline函数的地址,有兴趣可以跟进看看即可。
3.使用fs寄存器获取线程id和进程id
代码:
#include<iostream>
#include<windows.h>
#include<process.h>
using namespace std;
int main()
{
int processId = 0;
int threadId = 0;
__asm {
mov eax,fs:[0x18]
mov ecx,[eax+0x20]
mov processId,ecx
mov eax,[eax+0x24]
mov threadId,eax
}
cout << "processId = " << processId << endl;
cout << "threadId = " << threadId << endl;
cout << GetCurrentThreadId() << endl;
cout << _getpid() << endl;
system("pause");
}
当然,结果和任务管理器看也是一样的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构