sizeof(int)*nCount

本文详细介绍了在C语言中如何正确地将一个整型数组的内容复制到另一个数组中。通过对比两种不同的memcpy用法,解释了正确的数组复制方法,并强调了理解sizeof运算符的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

int  nCardIDs[13];

ZeroMemory(nCardIDs, sizeof(nCardIDs));


Test(nCardIDs, 13);



那么在Test(int  nCardIDs[], int  nCount)函数中:

void Test(int  nCardIDs[],  int  nCount)

{

int nCardTemp[13];

ZeroMemory(nCardTemp, sizeof(nCardTemp));


//memcpy(nCardTemp, nCardIDs, sizeof(nCardIDs));//这样的话,只复制了一份指针长度(4个字节)的数据

memcpy(nCardTemp, nCardIDs, sizeof(int) * nCount);//这样写才是复制整个数组的数据

}

服务器端 #define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll #define BUF_SIZE 1024 #define PORT 40000 int main() { //先输入文件名,看文件是否能创建成功 char filename[100] = { 0 }; //文件名 printf("Input filename to save: "); gets_s(filename); FILE* fp = fopen((const char*)filename, "wb"); //以二进制方式打开(创建)文件 if (fp == NULL) { printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(PORT); bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); listen(servSock, 20); SOCKADDR clntAddr; int nSize = sizeof(SOCKADDR); SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize); //循环接收数据,直到文件传输完毕 char buffer[BUF_SIZE] = { 0 }; //文件缓冲区 int nCount; while ((nCount = recv(clntSock, buffer, BUF_SIZE, 0)) > 0) { fwrite(buffer, nCount, 1, fp); } puts("File transfer success!"); //文件接收完毕后直接关闭套接字,无需调用shutdown() fclose(fp); closesocket(clntSock); closesocket(servSock); WSACleanup(); system("pause"); return 0; } 客户端 #define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define BUF_SIZE 1024 #define PORT 40000 int main() { //先检查文件是否存在 const char* filename = "C:\\Users\\user0\\Desktop\\mm.txt"; //文件名 FILE* fp = fopen(filename, "rb"); //以二进制方式打开文件 if (fp == NULL) { printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(PORT); connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); //循环发送数据,直到文件结尾 char buffer[BUF_SIZE] = { 0 }; //缓冲区 int nCount; while ((nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0) { send(sock, buffer, nCount, 0); } shutdown(sock, SD_SEND); //文件读取完毕,断开输出流,向客户端发送FIN包 recv(sock, buffer, BUF_SIZE, 0); //阻塞,等待服务器端接收完毕 fclose(fp); closesocket(sock); WSACleanup(); system("pause"); return 0; } 这两个文件传输的协议有无问题
最新发布
08-15
#pragma once #include "StdAfx.h" #include "SignatureScanning.h" DWORD Signature::FindSignature(HANDLE hProcess, std::string markCode, DWORD memBeginAddr, DWORD memEndAddr, DWORD retAddr[], int deviation, bool isAll)//deviation 偏移量 { //1F ?? 3B 44 -> 1f?3b44 -> 1f 3f 3b 44 ( 3f=='?' ) if (!markCode.empty()) { //去除所有空格 int index = 0; while ((index = markCode.find(' ', index)) >= 0)markCode.erase(index, 1); //删掉头部通配符 if (markCode[0] == 0x3F && markCode[1] == 0x3F)markCode.erase(0, 2); //特征码长度不能为单数 if (markCode.length() % 2 != 0) return 0; //特征码长度 int len = markCode.length() / 2; //Sunday算法模板数组的长度 int nSundayLen = len; //将特征码转换成byte型 BYTE *pMarkCode = new BYTE[len]; for (int i = 0; i < len; i++) { std::string tempStr = markCode.substr(i * 2, 2); if (tempStr == "??") { pMarkCode[i] = 0x3F; //0x3F == '?' if (nSundayLen == len) nSundayLen = i; } else pMarkCode[i] = (BYTE)strtoul(tempStr.c_str(), 0, 16); } //--------------------------end-------------------------// //Sunday算法模板数组赋值,+1防止特征码出现FF时越界 int aSunday[0xFF + 1] = { 0 }; for (int i = 0; i < nSundayLen; i++)aSunday[pMarkCode[i]] = i + 1; //起始地址 const DWORD dwBeginAddr = memBeginAddr; //结束地址 const DWORD dwEndAddr = memEndAddr; //当前读取的内存块地址 DWORD dwCurAddr = dwBeginAddr; //存放内存数据的缓冲区 BYTE *pMemBuffer = NULL; //计算参数retAddr[]数组的长度,该参数传入前一定要清0 int nArrayLength = 0; for (int i = 0;; i++) { if (*(retAddr + i) != 0) { nArrayLength = i; break; } } //偏移量 int nOffset; //数组下标:内存、特征码、返回地址, nCount=找到次数? int i = 0, j = 0, nCount = 0; //内存信息 MEMORY_BASIC_INFORMATION mbi; //扫描内存 while (dwCurAddr < dwEndAddr) { //查询地址空间中内存地址的信息 memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION));//mbi置零 if (::VirtualQueryEx(hProcess, (LPCVOID)dwCurAddr, &mbi, sizeof(mbi)) == 0) { //int error = GetLastError(); goto end; } //过滤内存空间, 根据内存的状态和保护属性进行过滤 //一般扫描(读写及执行)即可,速度极快,扫不到的话在尝试添加(读写)这一属性 if (MEM_COMMIT == mbi.State && //已分配的物理内存 //MEM_PRIVATE == mbi.Type || //私有内存,不被其他进程共享 //MEM_IMAGE == mbi.Type && //镜像 //PAGE_READONLY == mbi.Protect || //只读 PAGE_EXECUTE_READ == mbi.Protect || //读及执行 PAGE_READWRITE == mbi.Protect || //读写 PAGE_EXECUTE_READWRITE == mbi.Protect) //读写及执行 { //申请动态内存 if (pMemBuffer) { delete[] pMemBuffer; pMemBuffer = NULL; } pMemBuffer = new BYTE[mbi.RegionSize]; //读取进程内存 ReadProcessMemory(hProcess, (LPCVOID)dwCurAddr, pMemBuffer, mbi.RegionSize, 0); i = 0; j = 0; while (j < len) { nextAddr: if (pMemBuffer[i] == pMarkCode[j] || pMarkCode[j] == 0x3F) { i++; j++; } else { nOffset = i - j + nSundayLen; //判断偏移量是否大于缓冲区 if (nOffset > (int)mbi.RegionSize - len) break; //判断 aSunday模板数组 里有没有 内存偏移后的值,有则回溯,否则+1 if (aSunday[pMemBuffer[nOffset]]) { i = nOffset - aSunday[pMemBuffer[nOffset]] + 1; j = 0; } else { i = nOffset + 1; j = 0; } } } if (j == len) { //计算找到的目标地址: //特征码地址 = 当前内存块基址 + i偏移 - 特征码长度 //目标地址 = 特征码地址 + 偏移距离 //CALL(E8)跳转的地址 = E8指令后面的4个字节地址 + 下一条指令地址(也就是目标地址 + 5) retAddr[nCount] = dwCurAddr + i - len + deviation; /* if (isCall) { DWORD temp; memcpy(&temp, &pMemBuffer[i - len + deviation + 1], 4); retAddr[nCount] += 5; retAddr[nCount] += temp; } */ if (++nCount >= nArrayLength) { //传入的数组下标越界就结束搜索 goto end; } if (isAll) { i = i - len + 1; j = 0; goto nextAddr; } else { goto end; } } dwCurAddr += mbi.RegionSize; //取下一块内存地址 } else { dwCurAddr += mbi.RegionSize; } } end: //释放内存 if (pMemBuffer) { delete[] pMemBuffer; pMemBuffer = NULL; } delete[] pMarkCode; pMarkCode = NULL; return nCount; } return 0; } 为什么这我这个函数,查找不到内存中的字符串
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值