//Open a thread to get the processID and control the process DWORD WINAPI Thread_1 (LPVOID lpParam) { DWORD pProcessIds[1024],cbReturned,cProcesses; DWORD pProcessIdWanted = 0; TCHAR sProcessName[MAX_PATH] = TEXT("minesweeper.exe"); unsigned int i; if(!EnumProcesses(pProcessIds,sizeof(pProcessIds),&cbReturned)) { return 1; } //Number of Processes returned from Enum from Byte to # cProcesses = cbReturned / sizeof(DWORD); for(i=0;i<cProcesses;i++) { if(pProcessIds[i] != 0) { pProcessIdWanted = GetProcessIdByName(pProcessIds[i], sProcessName); if(pProcessIdWanted != 0) break; } } pProcessIdWanted ? cout<< pProcessIdWanted <<endl : cout<<"Process Not Found" << endl; GetProcessBaseAddr(pProcessIdWanted); return 0; }
int CMemUtil::writememory(DWORD processId, DWORD memAddress, int* value, DWORD size, bool addBaseAddress, bool useCache /*= true*/) { HANDLE dwHandle = gethandle(processId); if (dwHandle == NULL) return 1; void *ptr; if (addBaseAddress) ptr = (void *)(memAddress - 0x400000 + GetProcessBaseAddr(processId)); else ptr = (void *)memAddress; DWORD bytesWritten; if (useCache) { // Invalidate related cache entries DWORD alignedAddr = ((DWORD)ptr) & (0xFFFFFFFF - (MEMORY_CACHE_ENTRY_SIZE - 1)); DWORD alignOffset = ((DWORD)ptr) & (MEMORY_CACHE_ENTRY_SIZE - 1); DWORD endAddr = ((DWORD)ptr) + size; while (alignedAddr < endAddr) { m_memoryCache[alignedAddr].expirationTime = 0; alignedAddr += MEMORY_CACHE_ENTRY_SIZE; } } if (WriteProcessMemory(dwHandle, ptr, value, size, &bytesWritten)) { return 0; } else { if (::GetLastError() == ERROR_INVALID_HANDLE) { //FILE *f=fopen("C:/out.txt","a+"); //fprintf(f,"time %lld old %d,",time(NULL),dwHandle); dwHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_prevProcessId); //fprintf(f,"new %d\n",dwHandle); //fclose(f); m_prevProcessHandle = dwHandle; if (WriteProcessMemory(dwHandle, ptr, value, size, NULL)) return 0; } if (::GetLastError() == ERROR_NOACCESS) { dwHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, m_prevProcessId); m_prevProcessHandle = dwHandle; if (WriteProcessMemory(dwHandle, ptr, value, size, NULL)) return 0; } DWORD err = ::GetLastError(); CloseHandle(dwHandle); m_prevProcessId = -1; return err; } }
int CMemUtil::readmemory(DWORD processId, DWORD memAddress, char* result, DWORD size, bool addBaseAddress, bool useCache /*= true*/) { HANDLE dwHandle = gethandle(processId); if (dwHandle == NULL) return 1; void *ptr; if (addBaseAddress) ptr = (void *)(memAddress - 0x400000 + GetProcessBaseAddr(processId)); else ptr = (void *)memAddress; if (useCache) { DWORD alignedAddr = ((DWORD)ptr) & (0xFFFFFFFF - (MEMORY_CACHE_ENTRY_SIZE - 1)); DWORD alignOffset = ((DWORD)ptr) & (MEMORY_CACHE_ENTRY_SIZE - 1); DWORD bufOffset = 0; LARGE_INTEGER currentTimestamp; QueryPerformanceCounter(¤tTimestamp); while(bufOffset < size) { if (m_memoryCache[alignedAddr].expirationTime < currentTimestamp.QuadPart) { // Refresh the cache entry DWORD ret = readmemory(processId, alignedAddr, m_memoryCache[alignedAddr].value, MEMORY_CACHE_ENTRY_SIZE, 0, false); if (ret != 0) return ret; m_memoryCache[alignedAddr].expirationTime = currentTimestamp.QuadPart + m_cacheTimeoutTicks; } DWORD entryReadSize = min(size - bufOffset, MEMORY_CACHE_ENTRY_SIZE - alignOffset); // Load the entry data memcpy(result + bufOffset, (m_memoryCache[alignedAddr].value + alignOffset), entryReadSize); // After the first load, there's no longer an align alignOffset = 0; alignedAddr += MEMORY_CACHE_ENTRY_SIZE; bufOffset += entryReadSize; } return 0; } if (ReadProcessMemory(dwHandle, ptr, result, size, NULL)) { return 0; } else { if (::GetLastError() == ERROR_INVALID_HANDLE) { //FILE *f=fopen("C:/out.txt","a+"); //fprintf(f,"time %lld old %d,",time(NULL),dwHandle); dwHandle = NULL; for (int iter = 1000; iter > 0; iter--) { dwHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_prevProcessId); if (dwHandle) { char buf[111]; sprintf(buf, "iter %d", iter); if (iter != 1000) MessageBox(NULL, buf, "", 0); break; } Sleep(10); } //fprintf(f,"new %d\n",dwHandle); //fclose(f); m_prevProcessHandle = dwHandle; if (ReadProcessMemory(dwHandle, ptr, result, size, NULL)) return 0; } if (::GetLastError() == ERROR_NOACCESS) { CloseHandle(dwHandle); dwHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, m_prevProcessId); m_prevProcessHandle = dwHandle; if (ReadProcessMemory(dwHandle, ptr, result, size, NULL)) return 0; } if (::GetLastError() == ERROR_PARTIAL_COPY) { //Possibly Tibia has been killed //Test valid address; taCMemUtil::GetMemIntValue(-1) void *ptrTest = (void*)(0x0410000 + GetProcessBaseAddr(processId)); int resultTest; if (!ReadProcessMemory(dwHandle, ptrTest, &resultTest, 4, NULL)) { //try getting new handle dwHandle = NULL; for (int iter = 1000; iter > 0; iter--) { dwHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_prevProcessId); if (dwHandle) { char buf[111]; sprintf(buf, "iter %d", iter); if (iter != 1000) MessageBox(NULL, buf, "", 0); break; } Sleep(10); } m_prevProcessHandle = dwHandle; if (ReadProcessMemory(dwHandle, ptr, result, size, NULL)) { return 0; } else { DWORD terminatedStatus = 9999; if (GetExitCodeProcess(dwHandle, &terminatedStatus)) if (terminatedStatus != STILL_ACTIVE) //If Tibia is no longer active then close TA PostQuitMessage(0); } } else { //Tibia is still running but a bad memory address was given return 1; } //fprintf(f,"new %d\n",dwHandle); //fclose(f); } DWORD err = ::GetLastError(); CloseHandle(dwHandle); m_prevProcessId = -1; PostQuitMessage(0); return err; } }
int baseAdjust(int addr) { CMemReader& reader = CMemReader::getMemReader(); return addr - 0x400000 + GetProcessBaseAddr(); }