2013-04-26 5 views
0

dll을 디 컴파일했고 DLL의 함수 호출을 대신 (동일한 서명을 사용하여) 만든 사용자 정의 함수를 호출하여 바꾸려고합니다.디 컴파일 DLL의 함수 대체

어셈블리에서 함수가 호출되는 위치를 찾을 수있었습니다. 아무도 지금 내가해야 할 일을 설명 할 수 있습니까?

내 사용자 지정 함수를 별도의 dll에 둘 수 있습니까? 아니면 동일한 dll에 포함해야합니까?

어떻게 함수 호출을 새 함수로 바꿀 수 있습니까?

감사합니다.

+1

DLL을 패치하는 것이 더 쉬울 수도 있습니다. 텍스트 세그먼트 끝에 새 코드를 추가하고 처음에 추가 된 코드로 이전 함수로 점프합니다. –

+0

사실 나는 그것이 단지 선택이 아니라는 것을 깨달았습니다. 다른 DLL에서 함수로 이동하거나 함수를 호출해야합니다. 그게 가능하니? – Lukesmith

+0

외부 DLL에서 함수를 호출하는 방법에 대한 질문을 _details_로 업데이트 할 수 있으면 변경 사항을 반영하여 답변을 업데이트 할 것입니다. –

답변

3

실행 모듈을 패치하는 것이 더 쉬울 수도 있습니다. 텍스트 세그먼트 끝에 새 코드를 추가하고 처음에 추가 된 코드로 이전 함수로 점프합니다. 이렇게하면 컴파일되지 않은 버전의 DLL로 인해 발생할 수있는 문제를 처리 할 필요가 없습니다.

000D0880 push  ebp 
000D0881 mov   ebp,esp 
000D0883 sub   esp,0E0h 
000D0889 push  ebx 
000D088A push  esi 
000D088B push  edi 
000D088C lea   edi,[ebp-0E0h] 
000D0892 mov   ecx,38h 
000D0897 mov   eax,0CCCCCCCCh 

통화 단지 D0880에 JMP 명령어를 추가로 리디렉션하려면 : 예를 들어

여기 교체하려는 기존 기능의 시작입니다. 디버그 세션 중에 디스패치 된 출력을 깨끗하게하기 위해 점프 후에 NOP 명령어를 추가합니다. 꼭 필요한 것은 아니지만 편리합니다.

000D0880 jmp   NewFunction 
000D0885 nop 
000D0886 nop 
000D0887 nop 
000D0888 nop 
000D0889 push  ebx 
000D088A push  esi 
000D088B push  edi 

이제 텍스트 세그먼트 끝에 새 코드를 추가하고 세그먼트가로드되는 오프셋을 기준으로 주소를 계산합니다. 이렇게하면 실제로 텍스트 세그먼트에서 함수가 실제로 어디에 있는지 정확히 알 수 있으므로 디버깅 및 관리가 훨씬 쉬워집니다.

다른 in-process 실행 모듈에서 함수를 호출 할 수도 있습니다. 원래 함수와 다음 함수 모두의 오프셋을 이미 알고 있기 때문에 모듈의로드 주소를 기반으로 정확한 위치를 계산할 수 있습니다.

typedef void (*EXTPROC)(int a, int b); 

// Windows loads the dll at 0xC0000 
HMODULE hMod = LoadLibrary("some.dll"); 
// The function is at offset 0x10880 (from start of text segment) 
EXTPROC proc = CalculateAddress(hMod, 0x00010880); 
// Call proc at 0xd0880 
proc(0, 1); 

함수 CalculateAddress는 DLL의 기본 주소를 검색하고, 기능의 실제 주소를 계산하고, 그것의 포인터를 리턴한다. 결과는 앞의 예와 동일합니다 (0xD0880). 이제는 함수 포인터를 통해 호출 할 수있는 주소가 생겼습니다. 동일한 기술을 적용하여 추가 할 새 함수를 호출 할 수 있습니다. 함수의 오프셋도 알고 있습니다.

이동하려는 경우 내보내기 테이블을 해당 오프셋을 가리키는 새 항목으로 업데이트하고 GetProcAddress을 사용하여 직접 계산하지 않고도 주소를 검색 할 수 있습니다. 이렇게하면 DLL의 추가 섹션을 업데이트해야하기 때문에 패치 프로세스에 약간의 복잡성이 추가됩니다.

다른 DLL에있는 함수를 호출하는 것은 원본 함수의 런타임 패치를 수행하여 외부 함수의 주소를 호출해야하므로 약간 더 복잡합니다. 이를 위해서는 Rich 님이 제안한 내용을 살펴보고 this 문서에 설명 된대로 프록시 DLL을 만드는 것이 좋습니다.

+0

좋은 답변이지만, 실제로 다른 기능이 필요하다는 것을 깨달았습니다. 다른 dll. 다른 DLL에있는 함수를 호출 할 때 패치 할 수있는 방법이 있습니까? – Lukesmith

+0

외부 DLL의 함수 호출에서 프록시 DLL을 사용하여 외장 모듈에서 함수를 호출하는 방법에 대한 답변을 확장했습니다 (제안에 대해 Rich에게 감사드립니다). –

+0

멋진 답변입니다. 내보내기 테이블을 편집하는 방법을 설명해 주시겠습니까? 관심있는 기능을 수출 테이블에 추가 한 다음 외부 적으로 액세스 할 수 있기 때문에 쉬운 방법 일 것 같습니다. – Lukesmith