Created
June 27, 2019 05:52
-
-
Save caromdreamer/84b6ec81ffcc392536cc1ad4d26df54c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ChildView.cpp : CChildView 클래스의 구현 | |
| // | |
| #include "stdafx.h" | |
| #include "SearchM.h" | |
| #include "ChildView.h" | |
| #include "OpenDlg.h" | |
| #include "FindDlg.h" | |
| #include "ValueDlg.h" | |
| #ifdef _DEBUG | |
| #define new DEBUG_NEW | |
| #endif | |
| // CChildView | |
| CChildView::CChildView() | |
| : m_hProcess(NULL) | |
| { | |
| } | |
| CChildView::~CChildView() | |
| { | |
| OnFindClose(); | |
| if (m_hProcess) | |
| CloseHandle(m_hProcess); | |
| } | |
| BEGIN_MESSAGE_MAP(CChildView, CWnd) | |
| ON_WM_PAINT() | |
| ON_WM_CREATE() | |
| ON_WM_SIZE() | |
| ON_COMMAND(ID_FILE_OPEN_PROCESS, OnOpenProcess) | |
| ON_COMMAND(ID_MEM_FIRST, OnFindFirst) | |
| ON_COMMAND(ID_MEM_NEXT, OnFindNext) | |
| ON_COMMAND(ID_MEM_CANCEL, OnFindClose) | |
| ON_LBN_DBLCLK(IDC_VALUELIST, OnSetValue) | |
| END_MESSAGE_MAP() | |
| // CChildView 메시지 처리기 | |
| BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) | |
| { | |
| if (!CWnd::PreCreateWindow(cs)) | |
| return FALSE; | |
| cs.dwExStyle |= WS_EX_CLIENTEDGE; | |
| cs.style &= ~WS_BORDER; | |
| cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, | |
| ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL); | |
| return TRUE; | |
| } | |
| void CChildView::OnPaint() | |
| { | |
| CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트 | |
| // TODO: 여기에 메시지 처리기 코드를 추가합니다. | |
| // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오. | |
| } | |
| int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) | |
| { | |
| if (CWnd::OnCreate(lpCreateStruct) == -1) | |
| return -1; | |
| CRect rc; | |
| GetClientRect(&rc); | |
| if (m_ListBox.Create(WS_VISIBLE|WS_CHILD|WS_VSCROLL|LBS_NOTIFY, rc, this, IDC_VALUELIST) == FALSE) | |
| return -1; | |
| return 0; | |
| } | |
| void CChildView::OnSize(UINT nType, int cx, int cy) | |
| { | |
| CWnd::OnSize(nType, cx, cy); | |
| if (m_ListBox.m_hWnd) | |
| { | |
| m_ListBox.SetWindowPos(NULL, 0, 0, cx, cy, 0); | |
| } | |
| } | |
| void CChildView::OnOpenProcess() | |
| { | |
| COpenDlg dlg; | |
| if (dlg.DoModal() == IDOK) | |
| { | |
| if (m_hProcess) | |
| { | |
| CloseHandle(m_hProcess); | |
| } | |
| m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dlg.m_SelProcessID); | |
| } | |
| } | |
| void CChildView::OnFindFirst() | |
| { | |
| if (!m_hProcess) | |
| return; | |
| CFindDlg dlg; | |
| if (dlg.DoModal() == IDOK) | |
| { | |
| int iCondition = dlg.m_iCondition; | |
| int iCondValue = dlg.m_iCondValue; | |
| if (iCondition == COND_KEEP || iCondition == COND_INCREASE || iCondition == COND_DECREASE) | |
| { | |
| AfxMessageBox("처음 조건으로는 쓸 수 없습니다.", 0, 0); | |
| return; | |
| } | |
| FINDCONDPROC Procs[COND_CNT] = {FCAlways, FCKeep, FCIncrease, FCDecrease, | |
| FCEqual, FCAboveEqual, FCBelowEqual, FCAbove, FCBelow}; | |
| FINDCONDPROC Proc = Procs[iCondition]; | |
| OnFindClose(); | |
| MEMORY_BASIC_INFORMATION mbi; | |
| BYTE* pBaseAddr = NULL; | |
| DWORD dwFoundCount = 0; | |
| while ((int)pBaseAddr < 0x7FFF0000) | |
| { | |
| VirtualQueryEx(m_hProcess, pBaseAddr, &mbi, sizeof(mbi)); | |
| pBaseAddr += mbi.RegionSize; | |
| if (mbi.State & MEM_COMMIT) | |
| { | |
| MEMORY_SECTION* pMS = new MEMORY_SECTION; | |
| SAVED_SECTION* pSS = NULL; | |
| BYTE* pReadMemory = new BYTE[mbi.RegionSize]; | |
| BYTE* pCurMemory = pReadMemory; | |
| DWORD dwReadSize = 0; | |
| DWORD dwOffset = 0; | |
| DWORD dwSectionNo = 0; | |
| pMS->pBaseAddress = (BYTE*)mbi.BaseAddress; | |
| pMS->dwRegionSize = mbi.RegionSize; | |
| pMS->dwFirstOffset = 0; | |
| BOOL bRet = ReadProcessMemory(m_hProcess, pMS->pBaseAddress, pReadMemory, mbi.RegionSize, &dwReadSize); | |
| if (!bRet || mbi.RegionSize != dwReadSize) | |
| { | |
| delete pMS; | |
| delete []pReadMemory; | |
| continue; | |
| } | |
| for (DWORD dwOff=0; dwOff<dwReadSize; ++dwOff) | |
| { | |
| if (Proc(0, *pCurMemory, iCondValue)) | |
| { | |
| if (dwSectionNo == 0) | |
| { | |
| pMS->dwFirstOffset = dwOffset; | |
| dwOffset = 0; | |
| pSS = new SAVED_SECTION; | |
| pSS->pSavedMemory = NULL; | |
| pSS->dwSavedSize = 0; | |
| pSS->dwOffsetToNext = 0; | |
| ++dwSectionNo; | |
| } | |
| else if (pSS->pSavedMemory) // 새로운 SAVED_SECTION 시작 | |
| { | |
| pSS->dwOffsetToNext = dwOffset; | |
| dwOffset = 0; | |
| pSS = new SAVED_SECTION; | |
| pSS->pSavedMemory = NULL; | |
| pSS->dwSavedSize = 0; | |
| pSS->dwOffsetToNext = 0; | |
| ++dwSectionNo; | |
| } | |
| ++dwFoundCount; | |
| } | |
| else | |
| { | |
| if (dwSectionNo > 0 && pSS->pSavedMemory == NULL) | |
| { | |
| // dwOffset값은 복사시작부분부터의 거리, 즉 복사 크기 | |
| pSS->pSavedMemory = new BYTE[dwOffset]; | |
| pSS->dwSavedSize = dwOffset; | |
| CopyMemory(pSS->pSavedMemory, pCurMemory-dwOffset, dwOffset); | |
| pMS->vpSavedSection.push_back(pSS); | |
| } | |
| } | |
| ++dwOffset; | |
| ++pCurMemory; | |
| } | |
| if (dwSectionNo > 0 && pSS->pSavedMemory == NULL) | |
| { | |
| pSS->pSavedMemory = new BYTE[dwOffset]; | |
| pSS->dwSavedSize = dwOffset; | |
| CopyMemory(pSS->pSavedMemory, pCurMemory-dwOffset, dwOffset); | |
| pMS->vpSavedSection.push_back(pSS); | |
| } | |
| delete []pReadMemory; | |
| if (pMS->vpSavedSection.size()) | |
| m_vpMemSection.push_back(pMS); | |
| else | |
| delete pMS; | |
| } | |
| } | |
| if (dwFoundCount < 1000) | |
| UpdateList(); | |
| if (dwFoundCount == 0) | |
| { | |
| AfxMessageBox("찾지 못 했습니다.", 0, 0); | |
| OnFindClose(); | |
| } | |
| } | |
| } | |
| void CChildView::OnFindNext() | |
| { | |
| if (!m_hProcess) | |
| return; | |
| CFindDlg dlg; | |
| if (dlg.DoModal() == IDOK) | |
| { | |
| int iCondition = dlg.m_iCondition; | |
| int iCondValue = dlg.m_iCondValue; | |
| if (iCondition == COND_ALWAYS) | |
| { | |
| AfxMessageBox("처음 조건으로만 쓸 수 있습니다.", 0, 0); | |
| return; | |
| } | |
| FINDCONDPROC Procs[COND_CNT] = {FCAlways, FCKeep, FCIncrease, FCDecrease, | |
| FCEqual, FCAboveEqual, FCBelowEqual, FCAbove, FCBelow}; | |
| FINDCONDPROC Proc = Procs[iCondition]; | |
| DWORD dwFoundCount = 0; | |
| DWORD dwMSCnt = m_vpMemSection.size(); | |
| for (DWORD dwMSNo=0; dwMSNo < dwMSCnt; ++dwMSNo) | |
| { | |
| MEMORY_SECTION* pMS = m_vpMemSection[dwMSNo]; | |
| DWORD dwSSCnt = pMS->vpSavedSection.size(); | |
| vector<SAVED_SECTION*> vpNewSavedSection; | |
| SAVED_SECTION* pSS = NULL; | |
| DWORD dwIncOffset = pMS->dwFirstOffset; | |
| DWORD dwOffset = dwIncOffset; | |
| DWORD dwPrevOffset = dwOffset; | |
| DWORD dwSectionNo = 0; | |
| for (DWORD dwSSNo=0; dwSSNo < dwSSCnt; ++dwSSNo) | |
| { | |
| SAVED_SECTION* pOldSS = pMS->vpSavedSection[dwSSNo]; | |
| BYTE* pReadMemory = new BYTE[pOldSS->dwSavedSize]; | |
| BYTE* pCurMemory = pReadMemory; | |
| BYTE* pOldCurMemory = pOldSS->pSavedMemory; | |
| DWORD dwReadSize = 0; | |
| ReadProcessMemory(m_hProcess, pMS->pBaseAddress + dwIncOffset, pReadMemory, pOldSS->dwSavedSize, &dwReadSize); | |
| dwIncOffset += pOldSS->dwOffsetToNext; | |
| for (DWORD dwOff=0; dwOff<dwReadSize; ++dwOff) | |
| { | |
| if (Proc(*pOldCurMemory, *pCurMemory, iCondValue)) | |
| { | |
| if (dwSectionNo == 0) | |
| { | |
| pOldSS->dwOffsetToNext -= dwOffset - dwPrevOffset; | |
| pMS->dwFirstOffset = dwOffset; | |
| dwOffset = 0; | |
| pSS = new SAVED_SECTION; | |
| pSS->pSavedMemory = NULL; | |
| pSS->dwSavedSize = 0; | |
| pSS->dwOffsetToNext = 0; | |
| ++dwSectionNo; | |
| } | |
| else if (pSS->pSavedMemory) // 새로운 SAVED_SECTION 시작 | |
| { | |
| pOldSS->dwOffsetToNext -= dwOffset - dwPrevOffset; | |
| pSS->dwOffsetToNext = dwOffset; | |
| dwPrevOffset = 0; | |
| dwOffset = 0; | |
| pSS = new SAVED_SECTION; | |
| pSS->pSavedMemory = NULL; | |
| pSS->dwSavedSize = 0; | |
| pSS->dwOffsetToNext = 0; | |
| ++dwSectionNo; | |
| } | |
| ++dwFoundCount; | |
| } | |
| else | |
| { | |
| if (dwSectionNo > 0 && pSS->pSavedMemory == NULL) | |
| { | |
| // dwOffset값은 복사시작부분부터의 거리, 즉 복사 크기 | |
| pSS->pSavedMemory = new BYTE[dwOffset]; | |
| pSS->dwSavedSize = dwOffset; | |
| CopyMemory(pSS->pSavedMemory, pCurMemory-dwOffset, dwOffset); | |
| vpNewSavedSection.push_back(pSS); | |
| } | |
| } | |
| ++dwOffset; | |
| ++pCurMemory; | |
| ++pOldCurMemory; | |
| } | |
| if (dwSectionNo > 0 && pSS->pSavedMemory == NULL) | |
| { | |
| pSS->pSavedMemory = new BYTE[dwOffset]; | |
| pSS->dwSavedSize = dwOffset; | |
| CopyMemory(pSS->pSavedMemory, pCurMemory-dwOffset, dwOffset); | |
| vpNewSavedSection.push_back(pSS); | |
| } | |
| delete []pReadMemory; | |
| pOldSS->dwOffsetToNext += dwPrevOffset; | |
| dwPrevOffset = dwOffset = pOldSS->dwOffsetToNext; | |
| delete []pOldSS->pSavedMemory; | |
| delete pOldSS; | |
| } | |
| pMS->vpSavedSection.clear(); | |
| if (vpNewSavedSection.size()) | |
| { | |
| pMS->vpSavedSection.insert(pMS->vpSavedSection.begin(), vpNewSavedSection.begin(), vpNewSavedSection.end()); | |
| } | |
| else | |
| { | |
| m_vpMemSection.erase(m_vpMemSection.begin() + dwMSNo); | |
| --dwMSCnt; | |
| --dwMSNo; | |
| } | |
| } | |
| if (dwFoundCount < 1000) | |
| UpdateList(); | |
| if (dwFoundCount == 0) | |
| { | |
| AfxMessageBox("찾지 못 했습니다.", 0, 0); | |
| OnFindClose(); | |
| } | |
| } | |
| } | |
| void CChildView::OnFindClose() | |
| { | |
| if (!m_hProcess) | |
| return; | |
| while (m_vpMemSection.size()) | |
| { | |
| MEMORY_SECTION* pMS = m_vpMemSection.back(); | |
| while (pMS->vpSavedSection.size()) | |
| { | |
| delete []pMS->vpSavedSection.back()->pSavedMemory; | |
| delete pMS->vpSavedSection.back(); | |
| pMS->vpSavedSection.pop_back(); | |
| } | |
| delete pMS; | |
| m_vpMemSection.pop_back(); | |
| } | |
| } | |
| void CChildView::UpdateList() | |
| { | |
| ClearList(); | |
| DWORD dwMSCnt = m_vpMemSection.size(); | |
| for (DWORD dwMSNo=0; dwMSNo < dwMSCnt; ++dwMSNo) | |
| { | |
| MEMORY_SECTION* pMS = m_vpMemSection[dwMSNo]; | |
| DWORD dwSSCnt = pMS->vpSavedSection.size(); | |
| DWORD dwIncOffset = pMS->dwFirstOffset; | |
| for (DWORD dwSSNo=0; dwSSNo < dwSSCnt; ++dwSSNo) | |
| { | |
| SAVED_SECTION* pSS = pMS->vpSavedSection[dwSSNo]; | |
| for (DWORD dwOff=0; dwOff < pSS->dwSavedSize; ++dwOff) | |
| { | |
| CString str; | |
| str.Format("%08x", pMS->pBaseAddress + dwIncOffset + dwOff); | |
| int Index = m_ListBox.AddString(str); | |
| FINDING_ADDRESS* pFA = new FINDING_ADDRESS; | |
| pFA->pMS = pMS; | |
| pFA->pAddress = pMS->pBaseAddress + dwIncOffset + dwOff; | |
| m_ListBox.SetItemData(Index, (DWORD_PTR)pFA); | |
| } | |
| dwIncOffset += pSS->dwOffsetToNext; | |
| } | |
| } | |
| } | |
| void CChildView::ClearList() | |
| { | |
| DWORD dwItemCnt = m_ListBox.GetCount(); | |
| for (DWORD dwIndex=0; dwIndex < dwItemCnt; ++dwIndex) | |
| { | |
| FINDING_ADDRESS* pFA = (FINDING_ADDRESS*)m_ListBox.GetItemData(dwIndex); | |
| delete pFA; | |
| } | |
| m_ListBox.ResetContent(); | |
| } | |
| void CChildView::OnSetValue() | |
| { | |
| if (!m_hProcess) | |
| return; | |
| int Index = m_ListBox.GetCurSel(); | |
| if (Index != -1) | |
| { | |
| CValueDlg dlg; | |
| if (dlg.DoModal() == IDOK) | |
| { | |
| FINDING_ADDRESS *pFA = (FINDING_ADDRESS*)m_ListBox.GetItemData(Index); | |
| BYTE* pWritingMemory = new BYTE[dlg.m_ValueSize]; | |
| DWORD dwWrittenSize = 0; | |
| DWORD dwProtect = 0; | |
| BOOL bRet = TRUE; | |
| CopyMemory(pWritingMemory, &dlg.m_WriteValue, dlg.m_ValueSize); | |
| bRet = VirtualProtectEx(m_hProcess, pFA->pMS->pBaseAddress, pFA->pMS->dwRegionSize, PAGE_READWRITE, &dwProtect); | |
| if (!bRet) | |
| { | |
| AfxMessageBox("VirtualProtect 실패", 0, 0); | |
| } | |
| bRet = WriteProcessMemory(m_hProcess, pFA->pAddress, pWritingMemory, dlg.m_ValueSize, &dwWrittenSize); | |
| if (!bRet || dlg.m_ValueSize != dwWrittenSize) | |
| { | |
| AfxMessageBox("메모리 셋 실패", 0, 0); | |
| } | |
| VirtualProtectEx(m_hProcess, pFA->pMS->pBaseAddress, pFA->pMS->dwRegionSize, dwProtect, 0); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment