2011-01-02 4 views
2

코드 삽입 작동 방식을 이해하기 위해 minesweeper.exe를 변경하고 있습니다. 간단히 말해서, 지뢰 찾기를 시작하기 전에 메시지 상자를 보여주기를 바랍니다. 그래서, 나는 실행 파일에 "cave"를 찾은 다음 messagebox에 표시 할 문자열을 정의하고 messagebox를 호출합니다. 물론, 실행 파일의 모듈 진입 점에서 값을 변경하고 먼저 추가 코드로 이동 한 다음 자체 코드를 계속 진행해야합니다. 그래서 동굴에서 내가하는 일; 문자열 주소를 어셈블리, 머신 코드와 함께 스택에 푸시하는 방법

"hello starbuck",0 

push 0 //arg4 of MessageBoxW function 
push the address of my string //arg3, must be title 
push the address of my string //arg2, must be the message 
push 0 //arg1 
call MessageBoxW 
... 

지금 실행 변경 매번에서 코드의 메모리 주소 이후는 MessageBoxW 함수를 호출을 위해, 나는 MessageBoxW가 가져 오기 주소 테이블에 정의 된 주소의 오프셋을 제공, 메모리에로드됩니다. MessageBoxW 단지 call MessageBoxWIAT의에서 주소 1과 명령에 정의 된 경우 예를 들어, 주소 2 대신 call MessageBoxW 작성 에, 나는 call address2 - address1 쓰기입니다.

제 질문은 문자열의 주소를 스택에 넣기 위해 어떻게해야합니까? 예를 들어 ollydbg를 통해 이러한 변경 작업을 수행 할 경우 "hello starbuck"이라는 직접 주소를 사용하여 푸시하면됩니다. 그러나 실행 파일을 다시로드하거나 ollydbg 외부에서 실행하면 즉각적인 주소가 변경되기 때문에 당연히 실패합니다.

미리 감사드립니다. Yigit.

편집 : exe가 열릴 때마다 모듈 진입 점의 상위 단어가 변경되기 때문에이 문제가 발생합니다. 따라서 다른 문자열이 스택에 어떻게 푸시되는지 보려면 다음을 수행하십시오.

코드에서 "Destroy Canvas"문자열을 발견했습니다. 이것은 주소 : 00403E44에 있습니다. 주소 0042878E에는 PUSH 00403E44 (68 44 3E 40 00) 명령이 있습니다. 이는 문자열에 대한 포인터가 스택에 푸시되었음을 의미합니다. 그런 다음 UltraEdit에서 exe를 열어 해당 주소 인 00027D8E를 찾았습니다. 여기서 "68 44 3E 40 00"대신 "68 44 3E 00 01"이라고 씁니다. 이제 OllyDbg가 exe를로드하면이 코드가 업데이트된다는 것을 의미합니다. 00 01 ~ 40 00. 나는 다른 현을 보았고, 그들의 강요 지침도 마찬가지였다. 그래서 문자열을 푸시하기 위해 UltraEdit에서 "68 DA 9A 00 01"대신 "68 DA 9A 00 00"을 쓰면 업데이트 될 것입니다. 그러나 그렇지 않습니다. 이 후 OllyDbg에서 EXE를 열면 밀어 넣을 주소는 "01009ADA"로 남습니다.

그래서 이러한 "코드 업데이트"절차를 구성해야한다고 생각합니다. 어쩌면 재배치 테이블과 관련이 있을지 모르겠습니다.

다른 질문으로 질문해야 할 것 같습니까?

답변

0

귀하의 솔루션 :

추가 문자열은 UTF-16해야한다.

문자열 "Hello"의 경우 "H.e.l.l.o"로 점을 00h로 써야합니다.이 문자열의 끝이 있는지 확인 적어도 00h00h00h (3 X 0의) 이 또한 확인 당신은 MSGBOX 당신은 DWORD의 PTR로 전화 CAL 때 [] CALL의 DWORD PTR DS : [10010B8]

에서 세부 정보 :

로드 라이브러리 문자열 근처 (유니 코드가 아님) 근처에 UTF-16으로 문자열을 추가하십시오. 즉, 각 ASCII 문자는 00h로 구분되고 유니 코드 문자열 종료는 00h00h 이상이어야합니다 (00h가 표시됨). ollydbg의 덤프 창에 점으로 표시)

프로그램의 시작 지점에 다음과 같이 표시됩니다.

01003E21 PUSH 70 
01003E23 PUSH winmine_.01001390 
01003E28 CALL winmine_.0100400C 

푸시 (70) 라인을 더블 클릭하여 JMP 01004A5F로 교체 (는 쓰지 않는다 "winmine_을.")

01003E21 JMP winmine_.01004A5F 
01003E26 NOP 
01003E27 NOP 
01003E28 CALL winmine_.0100400C 

을 01004A5F에서 당신이 주입 코드 :

01004A5F PUSH 0 
01004A61 PUSH winmine_.01004A5F 
01004A66 PUSH winmine_.01004A5F 
01004A6B PUSH 0 
01004A6D CALL DWORD PTR[010010B8] ;msgbox 

을 진입 점에서 점프를 추가 할 때 삭제 한 원래 코드를 추가 한 다음 일반 프로그램 실행으로 돌아갑니다.

01004A72 PUSH 70 
01004A74 PUSH winmine_.01001390 
01004A79 JMP winmine_.01003E28 

MessageBoxW의 주소를 찾으려면 CTRL + N을 누르면 등록 된 함수의 정렬 된 목록이 표시됩니다.

문자열에 관해서는, 그것은 다음과 같습니다

01004A58 UNICODE "Hello",0 

을 즐길 수 있습니다.

원래 게시물 : exe에 문자열을 삽입 한 경우 OllyDbg에서 디스 어셈블리 창을 마우스 오른쪽 버튼으로 클릭하고 검색 -> 모든 참조 텍스트 문자열을 클릭합니다. 문자열과 주소를 찾을 수 있어야합니다.

다음은주의 깊게 읽어야 2 개 기사입니다 : 당신이 당신의 자신의 메시지와 방법으로 EXE에서 기존 (사용되지 않는) 문자열을 대체 할 수있는 방법 설명이 문서의 2 부에서

http://osix.net/modules/article/?id=633

사용자 정의 함수로 호출 할 수 있습니다. 이 문서의 2 부에서

http://osix.net/modules/article/?id=758

텍스트 섹션과 문자열과 방법을 그들에게 참조하는 방법에 대한 설명이있다.

이렇게하면 Windows 응용 프로그램을 다시 시작하기위한 충분한 정보를 얻을 수 있습니다.윈도우 게임 반전에 보너스 튜토리얼로

: http://osix.net/modules/article/?id=723 (프리셀) 다음

+0

불행히도 여기에 같은 문제가 있습니다. 예를 들어 첫 번째 기사에서 "push 0100131C"는 "You found the password"문자열의 포인터를 전달했습니다. 이제 0100131C는 해당 문자열의 현재 주소입니다. 따라서 그가 ollydbg에서 calc.exe를 시작하면 작동합니다. 그러나 그가 exe에 변경 사항을 저장하고 다시 외부로 시작하면 충돌이 발생합니다. 주소 0100131C는 관련이없는 어딘가를 지적하기 때문에. 그가 ollydbg를 닫은 후 다시 시작하고 calc.exe를 다시 열면 0100131C 주소가 "You found the password"문자열을 가리키고있는 것을 볼 수 있습니다. – Yigit

+0

그리고 그 이유는 exe가 시작될 때마다 다른 주소로로드되기 때문입니다. exe에서 코드와 문자열 간의 상대 거리가 변경되지는 않지만 실제 주소가 변경됩니다. – Yigit

+1

나는 기사를 썼다. 이 프로그램은 ollydbg 밖에서 충돌하지 않으며 문자열은 정확히 같은 위치에 있습니다. 당신은 아마 명백한 것을 놓치고있을 것입니다. 내 XP 버전의 지뢰 찾기에서 해보고 다시 해보겠습니다. –

0

문자열의 오프셋은 EXE에 포함되어 있으면 변경되지 않아야합니다. 자원으로로드되었거나 동적으로 할당되었거나 무엇입니까? 후자 중 하나 인 경우 동적으로 생성 된 주소를 푸시해야합니다. 그러나 정적 문자열은 항상 동일한 오프셋 주소로로드해야합니다.

+0

예 문자열의 오프셋은 변경되지 않으며 문자열은 실행 파일의 '.text'섹션에 있습니다. 하지만 내가 UltraEdit이나 다른 16 진수 편집기에서 exe를 열었고 내 문자열이 주소 0x000190DA에서 시작한다고 가정합니다. 이제 인수 전달을 위해 "push 0x000190DA"를 작성하면 실행 파일이로드 될 때 내 문자열과 다른 지점을 가리 킵니다. 따라서 "call MessageBoxW"명령이 "address2"에있는 경우 "push address2 - 0x000190DA"또는 무엇을 작성해야합니까? – Yigit

+0

나는 무엇이 일어나고 있는지 완전히 확신하지 못합니다. 제 이해는 주소의 세그먼트 부분은 응용 프로그램이로드 될 때마다 다를 수 있지만 주소의 오프셋 부분은 동일해야합니다. 따라서 EXE가 매번 다른 주소로로드 되더라도 세그먼트 만 달라야합니다. 내가 assember 한 이후로 꽤 오랜 시간이 걸렸지 만, 문자열 주소 (오프셋)가 지침에 포함되어 변경 될 수 없음을 알고 있습니다. 아마도 당신은 다른 일이있을 것입니다. –

0
내가 먼저 도끼 주소를 보낼 필요가 있다고 생각

및 그래서, 당신을 만들 도끼를

mov ax,OFFSET string1 ;or use LEA ax,string1 
push ax 

를 밀어 당신이해야 할 MessageBox :

mov ax,16   ;16 = Critical Icon (for example) 
push ax 
lea dx,title 
push dx 
lea dx,text 
push dx 
mov ax,0    ;0 is like NULL for the window's handle 
push ax 
call MesssageBox... 
+0

작동하지 않습니다. 주소의 하위 단어를 스택으로 푸시합니다. 대신 eax를 밀어 넣으려고하면 eax의 높은 단어는 임의적 인 것이므로 어쨌든 작동하지 않습니다. 여전히 EIP라는 단어를 찾아야합니다. 그러나 EIP는 읽을 수 없습니다. – Yigit

관련 문제