ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Runtime Memory Patch
    Mobile/Frida 2019. 12. 17. 07:15

     

    Windows의 CheatEngine처럼 App실행 중에 메모리를 스캔해서 특정 메모리를 패치하는 방법이다.

    FRIDA의 Process API와 Memory API를 활용하면 된다.


    Memory Patch Script

    function memscan()
    {
        var patched = false;
        var scan_result;
        
        // 프로세스에서 'rw-'영역 메모리 가져옴
        Process.enumerateRanges('rw-', { 
        
        // 'rw-'영역 Callback함수 정의
        onMatch: function(range) {
            if(!patched)
            {	// pattern: py0zz1
                scan_result = Memory.scanSync(range.base, range.size, '70 79 30 7a 7a 31'); 
    					            
                // 프로세스에서 가져온 'rw-'영역 메모리 주소, 크기
                console.log("[*] Base: " + range.base);
                console.log("[*] Size: " + range.size);
            }
            
            // pattern을 찾지 못했으면 Callback함수 종료
            if (scan_result.length == 0) { 
                return;
            }else // pattern 찾았을 때
            {
                var match = scan_result[0];
                
                // pattern 주소 출력 및 Hexdump 출력
                console.log('[*] Find Address ' + match.address);
                console.log(hexdump(match.address,{offset: 0, length: 32}));
                
                console.log("");
                
                // Memory Patch => I want to believe
                Memory.writeByteArray(match.address, [ 0x49,0x20,0x77,0x61,0x6e,0x74,0x20,0x74,0x6f,0x20,0x62,0x65,0x6c,0x69,0x65,0x76,0x65,0x00]);
                
                // Memory Patch 후, Hexdump 출력
                console.log('[*] Patched String ' + match.address);
                console.log(hexdump(match.address,{offset: 0, length: 32}));
                
                // Memory Patch가 완료되었으므로
                // patched플래그를 활성화하여 Memory.scanSync()이 실행되지 않도록 함
                scan_result.length = 0;
                patched = true;
            }
        },
        onComplete: function() { }
        });
    }

     

    먼저 Process.enumerateRanges('rw-')로 메모리의 'rw-'권한을 가진 영역들을 가져온다.

    그 다음 콜백함수를 정의해주면 되는데, onMatch와 onComplete 두 분기점을 기준으로 작성할 수 있다.

     

    onMatch('rw-'영역)일 때, Memory.scanSync( )로 패치할 특정 패턴을 탐색한다.

    패턴은 위와 같이 Hex값으로 줘야하며, 여기에서는 '70 79 30 7a 7a 31'(py0zz1)로 설정하였다.

     

    패턴을 찾으면, Memory.writeByteArray( )로 메모리 패치를 진행한다. *문자열 패치이기 때문에 writeByteArray를 사용

    여기에서는 'I want to believe'로 패치 하였다.

     

    [그림 1] Uncrackable1 - py0zz1입력

    메모리 패치 테스트는 OWASP Uncrackable1로 진행하였고, 입력한 py0zz1I want to believe로 패치하도록 하겠다.

     

    [그림 2] Memory Patch

    위 결과와 같이 0x12CC5C80에 저장된 'py0zz1' 문자열이 'I want to believe'로 패치된 것을 확인할 수 있다.

    댓글

Designed by Tistory.