기본 콘텐츠로 건너뛰기

[ ChatGPT ] 임의의 프로세스에 접근하여 임의의 변수값을 바꾸기 위한 방법

 질문 사항

1번 프로세스와 2번 프로세스가 있어. 1번이 운영중인데, 2번 프로세스에서 1번 프로세스의 임의의 메모리에 접근하여 그 메모리의 값을 바꾸고 싶어. 어떤 절차를 이용해야 하지?

답변 내용

1번 프로세스의 메모리에 2번 프로세스에서 접근하여 값을 변경하는 것은 매우 민감한 작업이며, 운영 체제에서는 일반적으로 이러한 작업을 보안과 안정성 때문에 제한합니다. 그러나 특수한 경우, 특히 시스템 프로그래밍이나 디버깅 목적으로는 특정 API를 사용하여 이러한 작업을 수행할 수 있습니다. 아래는 이러한 작업을 수행하기 위한 일반적인 절차를 설명합니다.

1. 프로세스 권한 확인 및 확보

  • 2번 프로세스가 1번 프로세스의 메모리에 접근하려면 충분한 권한이 있어야 합니다. 일반적으로 이는 관리자 권한이나 루트 권한이 필요합니다.
  • Windows에서는 SeDebugPrivilege를 활성화해야 할 수 있으며, Linux에서는 루트 권한이 필요할 수 있습니다.

2. 1번 프로세스의 핸들 획득

  • 2번 프로세스가 1번 프로세스의 메모리에 접근하려면 먼저 1번 프로세스의 핸들을 얻어야 합니다.

  • Windows:

    • OpenProcess 함수를 사용하여 1번 프로세스의 핸들을 얻습니다. 이 함수는 1번 프로세스의 프로세스 ID를 기반으로 접근합니다.

IntPtr processHandle = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, processId);

 

  • Linux:

    • Linux에서는 ptrace 시스템 호출을 사용하여 다른 프로세스의 메모리에 접근할 수 있습니다. 그러나 이 작업은 일반적으로 매우 제한적이며, 디버깅 목적으로 주로 사용됩니다.
    ptrace(PTRACE_ATTACH, target_pid, NULL, NULL);
    waitpid(target_pid, NULL, 0);

3. 1번 프로세스의 메모리 주소 계산

  • 1번 프로세스에서 수정하려는 변수나 데이터의 정확한 가상 메모리 주소를 알아야 합니다.
  • 만약 1번 프로세스에서 해당 주소를 알고 있다면 이를 활용할 수 있지만, 그렇지 않다면 메모리 스캔이나 디버깅 도구를 사용하여 해당 주소를 찾아야 합니다.

4. 1번 프로세스의 메모리 읽기/쓰기

  • 메모리 주소를 얻은 후, 2번 프로세스에서 해당 메모리에 접근하여 데이터를 읽거나 쓸 수 있습니다.

  • Windows:

    • ReadProcessMemoryWriteProcessMemory 함수를 사용하여 1번 프로세스의 메모리에서 데이터를 읽고 쓸 수 있습니다.
    byte[] buffer = new byte[4];  // 읽기/쓰기할 데이터 크기에 맞게 설정
    int bytesRead;
    if (ReadProcessMemory(processHandle, address, buffer, buffer.Length, out bytesRead))
    {
        // buffer에 읽어온 데이터가 저장됩니다.
    }

    int bytesWritten;
    byte[] dataToWrite = BitConverter.GetBytes(newValue);  // 새로운 값
    if (WriteProcessMemory(processHandle, address, dataToWrite, dataToWrite.Length, out bytesWritten))
    {
        // 메모리에 데이터 쓰기 성공
    }

  • Linux:

    • ptrace 시스템 호출로 메모리에 쓰기 작업을 수행할 수 있습니다.
    ptrace(PTRACE_POKEDATA, target_pid, target_addr, new_value);

5. 프로세스 및 권한 정리

  • 작업이 끝나면 핸들을 닫거나(CloseHandle), ptrace를 통해 프로세스를 분리(PTRACE_DETACH)해야 합니다.
  • 권한이 상승된 상태에서 작업을 했다면, 작업 후 권한을 해제하는 것도 중요합니다.

예시: Windows에서의 메모리 쓰기

using System; using System.Diagnostics; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesWritten); [DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr hObject); static void Main(string[] args) { int targetProcessId = 1234; // 1번 프로세스 ID IntPtr targetAddress = new IntPtr(0x12345678); // 변경하려는 메모리 주소 // 1번 프로세스 핸들 얻기 IntPtr processHandle = OpenProcess(0x1F0FFF, false, targetProcessId); if (processHandle == IntPtr.Zero) { Console.WriteLine("프로세스를 열 수 없습니다."); return; } // 변경할 데이터 int newValue = 42; byte[] dataToWrite = BitConverter.GetBytes(newValue); int bytesWritten; // 메모리 쓰기 if (WriteProcessMemory(processHandle, targetAddress, dataToWrite, dataToWrite.Length, out bytesWritten)) { Console.WriteLine($"메모리 주소 {targetAddress}에 {newValue} 값을 썼습니다."); } else { Console.WriteLine("메모리 쓰기 실패."); } // 핸들 닫기 CloseHandle(processHandle); } }



주의사항

  • 보안 문제: 다른 프로세스의 메모리에 접근하거나 수정하는 것은 보안상 큰 문제가 될 수 있습니다. 악의적인 사용은 법적으로 문제가 될 수 있으며, 시스템 안정성을 해칠 수 있습니다.
  • 프로그램 충돌 위험: 잘못된 메모리 접근이나 수정은 대상 프로세스가 예기치 않게 종료되거나 충돌을 일으킬 수 있습니다.
  • 관리자 권한: 이러한 작업은 대부분 관리자 권한에서 수행해야 합니다.

이러한 작업은 디버깅 목적으로 주로 사용되며, 일반적으로 권장되지 않는 접근 방식입니다. 프로덕션 환경에서는 가능한 한 피해야 하며, 반드시 필요한 경우에도 신중하게 수행해야 합니다.


--------------------------------------------------------------------------------------------

메모리 스캔이나 디버깅 도구를 사용하여 해당 주소를 찾는 법

  • 메모리 스캔 도구 Cheat Engine을 이용하여 메모리 주소 찾기
  • Cheat Engine 이란 - 위키 백과 인용
    • 치트 엔진(Cheat Engine, CE)은 마이크로소프트 윈도우 운영 체제용으로 다크 바이트가 개발한 자유-오픈 소스 기반 메모리 스캐너/디버거이다.[4] 치트 엔진은 대부분 컴퓨터 게임의 치트에 사용되며 종종 감지 우회를 위해 수정 및 재컴파일된다. 이 프로그램은 L. 스파이로의 메모리 해킹 소프트웨어, T서치, 아트머니와 닮은 면이 있다. 다양한 옵션과 함께 사용자가 입력한 값을 검색하여 사용자가 컴퓨터 메모리를 통해 검색과 정렬을 가능케 한다. 치트 엔진은 또한 치트 엔진과는 독립적으로 운용 가능한, 독립적인 트레이너를 생성할 수도 있으며 다른 사용자의 요청을 통해서나 사용자 포럼을 통해 발견된다.
  • 오프라인엣어 설치 가능한 버전은 7.2이며, 여기를 클릭하여 다운로드 받을 수 있다. ( 나무 위키 참조 )



댓글

이 블로그의 인기 게시물

[QT] 5.15.2 버전 다운로드와 설치하기

1. 버전 5.15.2를 설치하기 위해 QT 다운로드 사이트 에 접속하였으나 실행파일이 존재하지 않는다. 가장 최신의 실행파일은 ver5.14.2 이므로 일단 이것을 다운받아서 설치한다. ( 참고 사이트 - https://sloth-code.tistory.com/6#comment16833678 ) 다운 사이트  - https://bio.nic.funet.fi/pub/mirrors/download.qt-project.org/archive/qt/5.14/5.14.2/  ------------- 버전이 맞지 않으니 재 설치한다. 2.  5.15.2 버전에는 실행파일 exe가 없고 zip과 tar.gz 파일만 존재한다. ( https://bio.nic.funet.fi/pub/mirrors/download.qt-project.org/archive/qt/5.15/5.15.2/ ) OFFLINE_README.txt를 읽어보면 5.15 버전부터는 오픈 소스 오프라인 설치를 이용할 수 없다고 한다. 오프라인 설치를 원할 경우 다음 사이트 참조하라고 한다.  ( 원본:  The Qt Company offering changes, open source offline installers are not available any more since Qt 5.15. Read more about offering changes in the https://www.qt.io/blog/qt-offering-changes-2020 blog. If you need offline installers, please consider our new Qt for Small Business offering: https://www.qt.io/blog/available-now-qt-for-small-businesses ) - https://www.qt.io/blog/available-now-qt-for-small-businesses ...

C# dll 파일들을 지정 폴더에서 사용하기

C#으로 여러 프로세스를 생성할 때, 각각의 프로젝트에서 사용하는 dll을 공동으로 사용하게 된다. 이때 dll은 실행 파일과 같은 폴더내에 존재해야 실행할 수 있다. 같은 dll을 사용하고 관리하는 관점에서 복사하는 일은 효율성이 떨어지며 항상 버전에 신경을 써야 하는 불편함이 있다. 이와 같은 비효율성을 제거하고자 실행파일과 다른 폴더에 있는 dll에 접근하는 방법으로 다음과 같은 방법을 사용하고자 한다. 코드를 수정하지 않고 지정할 수 있는 방법이 가장 편리하고 단순하겠지만 이와 같은 방법은 서브 폴더를 이용하는 방법밖에는 없다. dll이 필요할 때 발생되는 이벤트 핸들러를 추가하고 이를 등록하여 지정된 폴더를 사용할 수 있도록 코드를 추가하여 해결한다. 참고 사이트:  http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNo=8&no=169705&ref=169702 * dll 필요할 때 발생되는 이벤트 핸들러 추가 static   System.Reflection.Assembly RsveAssem( object   sender, ResolveEventArgs args) {      System.Reflection.Assembly thisAss = System.Reflection.Assembly.GetExecutingAssembly();      var name = args.Name.Substring(0, args.Name.IndexOf( ',' )) +  ".dll" ;             if ( name ==  "abc.dll"   )      {    ...

[MongoDB] C# 으로 작성한 응용 프로그램에서 몽고DB 접근할 때 발생하는 에러

1. System.IO.FileNotFoundException - 해당 기능을 수행할 때 작업 PC에서 발생하지 않는 메시지가 사용자 PC에서 발생하여 해결하기 위해 정리한다. - .Net Framework 4.6.1 에러 메시지 +-----------------------------------------------------------------------------------------------+ System.IO.FileNotFoundException: 파일이나 어셈블리 'System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 또는 여기에 종속되어 있는 파일이나 어셈블리 중 하나를 로드할 수 없습니다. 지정된 파일을 찾을 수 없습니다. 파일 이름: 'System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'    위치: MongoDB.Driver.Core.Connections.ClientDocumentHelper.CreateOSDocument()    위치: System.Lazy`1.CreateValue()    위치: System.Lazy`1.LazyInitValue()    위치: MongoDB.Driver.Core.Connections.ClientDocumentHelper.CreateClientDocument(String applicationName)    위치: MongoDB.Driver.Core.Connections.ConnectionInitializer..ctor(String applicationName, IReadOnl...