진격의 안드로이드 주입술 <둘>

4673 단어 이동 안전
계속하다
에서 나는 기본적인 사고방식을 한 번 묘사하고 이어서 우리를 위해 먼저 주입부터 시작한다.
부어 넣다
분류하다
우리가 평소에 말한 코드 주입은 주로 정태와 동태 두 가지 방식이다
  • 정적 주입은 실행 가능한 파일을 대상으로 한다. 예를 들어 평소에 우리가 ELF, DEX 파일을 수정하는 등 관련 보조 도구도 많다. 예를 들어 IDA, JEB, ApkTool 등이다.
  • 동적 주입은 프로세스를 대상으로 한다. 예를 들어 프로세스를 수정하는 레지스터, 메모리 값 등이다.

  • 동태와 정태의 가장 큰 차이점은 동태는 원본 파일을 변경할 필요가 없지만 높은 권한(보통 루트 권한)이 필요하고 기술적 함량이 높다는 것이다.
    바탕
    동적 주입 기술은 본질적으로 일종의 스케줄링 기술이다.평소에 우리가 프로세스를 디버깅할 때 어떤 기능을 할 수 있는지 생각해 보세요.일반적으로 다음과 같은 항목이 있습니다.
  • 변수 값 보기
  • 변수 값 수정
  • 추적 프로세스 점프
  • 프로세스 호출 창고 보기
  • 동적 주입은 일반적인 디버깅에 비해 가장 큰 차이는 동적 주입이
    '자동화 디버깅을 하고 사용자 정의 동적 링크 라이브러리를 불러오는 과정'에 도달한다. 자동화란 코드를 통해 이루어지는 것이다. 리눅스에서 Ptrace를 통해 위의 모든 기능을 완성할 수 있다. 물론 Ptrace 기능은 비교적 원시적이다. 평소 디버깅 중의 기능은 고위층 논리 봉인을 많이 해야만 실현할 수 있다.
    다음 장과 절을 읽기 전에 man 문서를 읽어보는 것을 강력히 권장합니다. 여기 있습니다.
    의 목적
    일반적으로 우리는 하나의 프로세스를 주입해야 하는데 주로 다음과 같은 몇 가지 목적이 있다.
  • 목표 프로세스의 기능을 강화한다.
  • 목표 프로세스 결함 복구;
  • 납치 목표 프로세스 함수;
  • 목표 프로세스 데이터 훔치기;
  • 목표 프로세스 데이터 변경;

  • 프로세스
    위의 그림에서 보듯이 프로세스 A가 프로세스 B에 주입된 후 레지스터와 메모리를 수정하여 프로세스 B로 하여금 사용자 정의 동적 라이브러리 a를 불러오게 한다. a가 불러온 후에 a는 dex 파일을 불러오는 등 다른 모듈을 불러오려고 한다. 구체적인 주입 과정은 다음과 같다.
  • ATTATCH, 목표 프로세스를 지정하고 디버깅을 시작합니다.
  • GETREGS, 목표 프로세스의 레지스터를 획득하여 현장에 저장;
  • SETREGS는 PC 등 관련 레지스터를 수정하여 mmap을 가리키도록 한다.
  • POPETEXT, so path를 mmap 신청의 주소 공간에 쓰기;
  • SETRESG는 PC 등 관련 레지스터를 수정하여 dlopen을 가리키도록 한다.
  • SETREGS, 현장 복구;
  • DETACH, 디버깅을 해제하고 복구하기;

  • 상술한 것은 간소화된 과정으로 전체 주입된 코드를 나는github, 주소에 업로드했다https://github.com/boyliang/Poison
    so가 dlopen에 의해 목표 프로세스에 불러온 후에 우리는 so의 논리를 실행해야 한다. 비교적 복잡한 방법은 ptrace로 레지스터를 수정하는 방법을 사용하여 목표 프로세스가dlsym를 호출해서 우리의 함수 주소를 찾도록 하는 것이다.비교적 간단한 방법은 두 가지가 있는데 다음과 같다.
  • gcc의 사전 컴파일 명령 사용하기attribute__ ((__constructor__)),작용은 so가 불러오면 함수가 자동으로 실행되는 것이다.
  • __attribute__ ((__constructor__))
    void Main() {
     LOGI(">>>>>>>>>>>>>I am in, I am a bad boy 1!!!!<<<<<<<<<<<<<
  • c++ 전역 대상을 사용하여 초기화하면 구조 함수가 자동으로 실행됩니다.
  • void Main();
    
    static void* _main(void*){
    	Main();
    	return NULL;
    }
    
    class EntryClass {
    public:
    
    	EntryClass() {
    		pthread_t tid;
    		pthread_create(&tid, NULL, _main, NULL);
    		pthread_detach(tid);
    	}
    
    } boy;

    예제 1
    다음 예는 ptrace를 통해 주입된 예입니다. 두 부분의 코드와 관련이 있습니다. 한 부분은 목표 프로세스 코드를host로 기록하고, 다른 한 부분은 우리가 주입한 so 코드를libmyso로 기록합니다.so
    Host 코드
    세 개의 원본 파일을 포함하는데 각각 demo1.c,inso.h, inso.c
    /*
     * inso.h
     *
     *  Created on: 2014 6 24 
     *      Author: boyliang
     */
    
    
    __attribute__ ((visibility ("default"))) void setA(int i);
    
    __attribute__ ((visibility ("default"))) int getA();
    /*
     * inso.c
     *
     *  Created on: 2014 6 24 
     *      Author: boyliang
     */
    
    #include 
    #include "inso.h"
    
    static int gA = 1;
    
    void setA(int i){
    	gA = i;
    }
    
    int getA(){
    	return gA;
    }
    /*
     * demo1.c
     *
     *  Created on: 2014 6 24 
     *      Author: boyliang
     */
    
    #include 
    #include 
    
    #include "inso.h"
    #include "log.h"
    
    int main(){
    
    	LOGI("DEMO1 start.");
    
    	while(1){
    		LOGI("%d", getA());
    		setA(getA() + 1);
    		sleep(2);
    	}
    
    	return 0;
    }

    libmyso.so 코드
    /*
     * myso.c
     *
     *  Created on: 2014 6 24 
     *      Author: boyliang
     */
    
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include  "log.h"
    
    __attribute__ ((__constructor__))
    void Main() {
    	LOGI(">>>>>>>>>>>>>I am in, I am a bad boy 1!!!!<<<<<<<<<<<<<

    호출
    주입 프로그램, 나는 그것을 Poison이라고 명명하는데, 사용 방법은 Poison이다.다음은 샘플 출력 디스플레이입니다.
    I/TTT     (  594): DEMO1 start.
    I/TTT     (  594): 1
    I/TTT     (  594): 2
    I/TTT     (  594): 3
    I/TTT     (  594): 4
    I/TTT     (  594): 5
    I/TTT     (  594): 6
    I/TTT     (  594): 7
    I/TTT     (  594): >>>>>>>>>>>>>I am in, I am a bad boy 1!!!!<<<<<<<<<<<<<<
    I/TTT     (  594): 999
    I/TTT     (  594): 1000
    I/TTT     (  594): 1001
    실행해야 한다./poison/data/local/tmp/libmyso.so594 이후 출력에 특정 문자열이 바로 나타났고 출력된 데이터가 999로 바뀌어 우리가 주입에 성공했음을 증명했다.
    예제 코드
    상술한 예시에서 코드와 관련된 것을 나는github에 발표했다. 여러분이 코드를 연구하고 싶다면https://github.com/boyliang/injection_by_ptrace
    '셋'에서 안드로이드에 특유한 주입 기술을 하나 더 소개할 테니 기대해 주세요.

    좋은 웹페이지 즐겨찾기