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;
}

image

这是某一次的输出结果,因为vs2015默认开启了随机基址。

image

不过不影响什么,偏移量都是固定的。

理解的好方法就是用OD或者x32dbg调试一下。

image

003212B3,这是等下inline函数和main里面调用_ReturnAddress(),输出的地址

image

image

其他的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");
}

当然,结果和任务管理器看也是一样的。

posted @ 2022-03-24 19:07  念秋  阅读(59)  评论(0编辑  收藏  举报