안드로이드 기타/Frida
Frida 메모리(Memory) 모듈 정리
naroSEC
2023. 7. 12. 21:33
개요
Frida 스크립트 작성 시 C/C++ 로 작성된 네이티브 함수를 후킹할 때 인자 값 변조 및 확인을 위해 자주 사용되는 메모리(Memory) 모듈의 문법에 관해서 정리를 하고자 포스팅 한다. 해당 포스팅은 완결 판이 아니며, 추후 계속 추가될 예정이다.
Memory 모듈 사용법 및 설명
Memory 모듈이란?
앱의 메모리에 접근하고 조작하는 기능을 제공하며, 메모리 모듈을 사용하여 특정 주소의 메모리를 읽거나 쓰는 것이 가능하고 메모리 주소에 대한 포인터를 조작, 블록을 할당 및 해제 할 수 있도록 지원되는 모듈이다.
문법 및 사용법 예시
[ Memory.read ]
Memory.readInt(address)
address로 지정한 메모리 주소에서 4바이트 정수 데이터를 읽어 반환한다.
예: var value = Memory.readInt(buffer);
Memory.readInt8(address)
address로 지정한 메모리 주소에서 1바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readInt8(buffer);
Memory.readUInt8(address)
address로 지정한 메모리 주소에서 1바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readUInt8(buffer);
Memory.readInt16(address)
address로 지정한 메모리 주소에서 2바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readInt16(buffer);
Memory.readUInt16(address)
address로 지정한 메모리 주소에서 2바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readUInt16(buffer);
Memory.readInt32(address)
address로 지정한 메모리 주소에서 4바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readInt32(buffer);
Memory.readUInt32(address)
address로 지정한 메모리 주소에서 4바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readUInt32(buffer);
Memory.readInt64(address)
address로 지정한 메모리 주소에서 8바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readInt64(buffer);
Memory.readUInt64(address)
address로 지정한 메모리 주소에서 8바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readUInt64(buffer);
Memory.readByteArray(address, size)
address로 지정한 메모리 주소에서 size만큼의 데이터를 읽어 바이트 배열로 반환한다.
예: var result = Memory.readByteArray(buffer, 16);
Memory.readU8(address)
address로 지정한 메모리 주소에서 1바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readU8(buffer);
Memory.readS8(address)
address로 지정한 메모리 주소에서 1바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readS8(buffer);
Memory.readU16(address)
address로 지정한 메모리 주소에서 2바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readU16(buffer);
Memory.readS16(address)
address로 지정한 메모리 주소에서 2바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readS16(buffer);
Memory.readU32(address)
address로 지정한 메모리 주소에서 4바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readU32(buffer);
Memory.readS32(address)
address로 지정한 메모리 주소에서 4바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readS32(buffer);
Memory.readU64(address)
address로 지정한 메모리 주소에서 8바이트 부호 없는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readU64(buffer);
Memory.readS64(address)
address로 지정한 메모리 주소에서 8바이트 부호 있는 정수 데이터를 읽어 반환한다.
예: var value = Memory.readS64(buffer);
Memory.readUtf8String(address)
address로 지정한 메모리 주소에서 UTF-8 형식의 문자열 데이터를 읽어 반환한다.
예: var str = Memory.readUtf8String(buffer);
Memory.readCString(address)
address로 지정한 메모리 주소에서 null 종료 C 문자열 데이터를 읽어 반환한다.
예: var str = Memory.readCString(buffer);
Memory.readByteArray(address, size)
address로 지정한 메모리 주소에서 size만큼의 데이터를 읽어 바이트 배열로 반환한다.
예: var result = Memory.readByteArray(buffer, 16);
[ Memory.write ]
Memory.writeByteArray(address, bytes)
bytes 배열의 데이터를 address로 지정한 메모리 주소에 쓴다.
예: var bytes = [0x41, 0x42, 0x43]; Memory.writeByteArray(buffer, bytes);
Memory.writeU8(address, value)
1바이트 부호 없는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeU8(buffer, 0x41);
Memory.writeS8(address, value)
1바이트 부호 있는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeS8(buffer, -1);
Memory.writeU16(address, value)
2바이트 부호 없는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeU16(buffer, 0x4142);
Memory.writeS16(address, value)
2바이트 부호 있는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeS16(buffer, -12345);
Memory.writeU32(address, value)
4바이트 부호 없는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeU32(buffer, 0x41424344);
Memory.writeS32(address, value)
4바이트 부호 있는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeS32(buffer, -12345678);
Memory.writeU64(address, value)
8바이트 부호 없는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeU64(buffer, 0x4142434445464748);
Memory.writeS64(address, value)
8바이트 부호 있는 정수 value를 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeS64(buffer, -1234567890);
Memory.writeUtf8String(address, string)
string을 UTF-8 형식으로 인코딩하여 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeUtf8String(buffer, "Hello");
Memory.writeCString(address, string)
string을 null 종료 C 문자열로 변환하여 address로 지정한 메모리 주소에 쓴다.
예: Memory.writeCString(buffer, "Hello");
[ 그 외 자주 사용하는 함수 ]
Memory.protect(address, size, protection)
address로 지정한 메모리 주소에서 size만큼의 메모리 보호 속성을 protection으로 설정합니다. protection은 --- (쓰기/읽기/실행 불가능), r-- (읽기만 가능), rw- (읽기/쓰기 가능) 등의 형식을 가진다.
예: Memory.protect(buffer, 64, 'rw-');
Memory.scan(address, size, pattern)
address로 지정한 메모리 주소에서 size만큼의 메모리 영역에서 pattern에 일치하는 값을 찾아 해당 주소의 배열로 반환한다.
예: var results = Memory.scan(buffer, 64, '01 23 45 ?? 67');
Memory.findPattern(base, size, pattern)
base로 지정한 메모리 주소부터 size만큼의 메모리 영역에서 pattern에 일치하는 첫 번째 주소를 찾아 반환한다.
예: var address = Memory.findPattern(Module.findBaseAddress('libfoo.so'), 0x10000, 'AB CD EF');
Memory.compare(address, pattern)
address로 지정한 메모리 주소와 pattern을 비교하여 값이 일치하는지 여부를 확인한다.
예: var isMatch = Memory.compare(buffer, [0x61, 0x62, 0x63]);
Memory.patchCode(address, size, callback)
address로 지정한 메모리 주소에서 size만큼의 코드를 임시적으로 변경하기 위해 callback 함수를 호출한다.
예: Memory.patchCode(buffer, 64, function (code) { ... });