programing

두 프로세스(C, Windows) 간 메모리 공유

javamemo 2023. 10. 7. 09:06
반응형

두 프로세스(C, Windows) 간 메모리 공유

이전에 질문했던 것에 대한 답을 찾지 못했기 때문에 다른 접근법을 시도하고 있습니다.

두 프로세스 간에 메모리를 공유할 수 있는 방법이 있습니까?

두 번째 프로세스는 더 이상 지원되지 않는 레거시 프로그램이기 때문에 주입을 통해 정보를 얻습니다.

제 생각은 코드를 거기에 주입하는 것입니다. 주입된 프로그램에 전달하는 구조에서 주소(또는 무엇이든)를 실행해야 하는 데이터가 있는 공유 메모리로 전달하는 것입니다.데이터를 받으면 주입된 스레드 내부에 변수를 채울 것입니다.

이게 가능할까요? 어떻게요?

코드는 감사합니다.

편집:

확실하지 않은 것 같아서 명확히 해두겠습니다.주사를 놓을 줄 압니다이미 하고 있습니다.여기서 문제는 주사기에 동적 데이터를 전달하는 것입니다.

Windows에서 파일 매핑 API를 통해 공유 메모리를 지원하지만 MapViewOfFileEx에서 프로세스 인수를 사용하지 않으므로 공유 메모리 매핑을 다른 프로세스에 직접 주입할 수는 없습니다.

그러나 VirtualAllocExWriteProcessMemory를 사용하여 다른 프로세스에 메모리를 할당하여 일부 데이터를 주입할 수 있습니다.DuplicateHandle을 사용하여 핸들에 복사한 다음 MapViewOfFileEx라는 스텁을 주입하면 다른 프로세스에서 공유 메모리 매핑을 설정할 수 있습니다.어차피 코드를 주입하게 될 것 같기 때문에, 이것은 당신에게 잘 맞을 것입니다.

요약하자면 다음과 같습니다.

  • CreateFileMapping with INVALL_HANDLE_VALUE for hFile, NULL for lpName을 호출하여 익명 공유 메모리 세그먼트 핸들을 만듭니다.
  • DuplicateHandle을 사용하여 이 핸들을 대상 프로세스에 복사합니다.
  • flAllocation과 함께 VirtualAllocEx를 사용하여 코드에 일부 메모리 할당= MEM_COMIT | MEM_REVERSE 및 flProtect = PAGE_EXECUTE_READWRITE를 입력합니다.
  • WriteProcessMemory를 사용하여 스터브 코드를 이 메모리에 씁니다.이 스텁은 아마 어셈블러에 적어야 할 것입니다.여기 어딘가에 핸들을 써서 DupplyHandle에서 핸들을 넘겨주세요.
  • CreateRemote를 사용하여 스터브 실행.그런 다음 스텁이 얻은 핸들을 사용하여 MapViewOfFileEx를 호출해야 합니다.그러면 프로세스는 공통 공유 메모리 세그먼트를 갖게 됩니다.

스터브가 외부 라이브러리를 로드하는 경우(즉, LoadLibrary(LoadLibrary의 주소를 찾는 것은 리더에게 연습으로 남겨짐) 라이브러리의 dll메인 진입 지점에서 작업을 수행하면 좀 더 수월해질 수 있습니다.이 경우 이름이 지정된 공유 메모리를 사용하는 것이 DuplicateHandle로 빈둥거리는 것보다 더 간단할 수 있습니다.자세한 내용은 CreateFileMapping에 대한 MSDN 문서를 참조하되, 기본적으로 hFile의 경우 INVALL_HANDLE_VALUE를, lpName의 경우 이름을 전달합니다.

편집: 실제 코드 주입이 아닌 데이터 전달이 문제이므로 몇 가지 옵션이 있습니다.

  1. 가변 크기의 공유 메모리를 사용합니다.스터브는 공유 메모리의 크기와 이름 또는 핸들을 가져옵니다.데이터를 한 번만 교환해야 하는 경우에 적합합니다.생성 후 공유 메모리 세그먼트의 크기를 쉽게 변경할 수 없습니다.
  2. 명명된 파이프를 사용합니다.스터브가 파이프의 이름이나 손잡이를 가져옵니다.그런 다음 적절한 프로토콜을 사용하여 변수 크기의 블록을 교환할 수 있습니다. 예를 들어 size_t를 길이로 작성한 다음 실제 메시지를 작성합니다.또는 PIPE_TYPE_MESSAGE 및 PIPE_READMODE_MESSAGE를 사용하고, ERROR_MORE_DATA를 관찰하여 메시지가 끝나는 위치를 확인할 수 있습니다.여러 번 데이터를 교환해야 하는 경우에 적합합니다.

편집 2: 스터브에 대한 핸들 또는 포인터 저장소를 구현하는 방법에 대한 스케치는 다음과 같습니다.

.db B8            ;; mov eax, imm32
.dl handle_value  ;; fill this in (located at the start of the image + one byte)
;; handle value is now in eax, do with it as you will
;; more code follows...

고정된 이름을 사용할 수도 있는데, 아마 더 간단할 것입니다.

메모리 매핑 파일을 사용해 볼 수 있습니다.

이것은 좀 더 단계별로 상세하게 설명해 줍니다.

공유 메모리를 사용할 수 있습니다.

파이프(메모리용)나 직렬화(객체용)를 사용하려고 했습니까?파일을 사용하여 프로세스 간의 메모리를 관리할 수 있습니다.소켓은 공정간 통신을 하기에도 좋습니다.

메모리 매핑은 바람직한 방법이며, 영구적인 메모리 공간을 생성할 필요도 없습니다. 메모리를 공유하는 모든 프로세스가 종료되면 메모리 영역이 범위를 벗어납니다.다른 방법들도 있습니다.하나의 C 앱에서 다른 앱으로 데이터를 빠르고 더러운 방식으로 전달하는 것은 단지 OS를 사용하는 것입니다.: app1 | app2. 이로 인해 app2가 app1의 출력 대상이 되거나 app1의 printf 명령이 app2로 전송됩니다(이것을 piping이라고 합니다).

Boost를 사용해 볼 수 있습니다.두 프로세스 간의 의사소통을 위한 인터프로세스.그러나 이전에 지원되지 않는 기존 소프트웨어에 코드를 주입하려면 WriteProcessMemory를 사용하는 @bdonlan 방식을 사용해야 합니다.

Windows(윈도우)를 말씀하시는 경우, 각각의 가상 주소 공간에서 라이브로 처리하는 것이 주요 장애 요인입니다.안타깝게도 정상적인 메모리 주소를 이 과정에서 저 과정으로 전달하여 기대했던 결과를 얻을 수는 없습니다.(반면 스레드는 모두 동일한 주소 공간에 살고 있으므로 스레드는 동일한 방식으로 메모리를 볼 수 있습니다.)

그러나 Windows(윈도우)에는 공유 메모리 공간이 있으므로 올바르게 관리하려면 매우 주의해야 합니다.공유 메모리 공간에 공간을 할당하는 모든 프로세스는 해당 메모리를 명시적으로 해제할 책임이 있습니다.이는 프로세스가 소멸되면 어느 정도 사라지는 로컬 메모리와는 대조적입니다.

공유 메모리 공간을 사용하여 세계를 점령하는 방법에 대한 몇 가지 아이디어는 이 MSDN 샘플 문서를 참조하십시오.어, 레거시 소프트웨어와의 인터페이스.아니면 뭐든 :) 결국 무엇을 하게 되든 행운을 빌어요!

언급URL : https://stackoverflow.com/questions/1200998/sharing-memory-between-two-processes-c-windows

반응형