안 드 로 이 드 네 이 티 브 디 버 깅
사고 하 다.
이전에 다른 사람의 암호 화 된 것 을 어떻게 디 버 깅 하고 시도 하 는 지 연 구 했 기 때문에 현재 의 체험 은 다음 과 같다.
사실 중요 한 것 은 당신 이 어떻게 암호 화 하 는 지, 중요 한 것 은 어떻게 다른 사람 에 게 당신 이 어떻게 암호 화 하 는 지 알 리 지 않 는 지 하 는 것 입 니 다.
이러한
프로그램 과 같이 나 는 심지어 네가 어떻게 암호 화 하 는 지 전혀 관심 을 가지 지 않 아 도 된다. 암호 화 알고리즘 이 무엇 인지 나 는 네가 복호화 한 후에 그 자원 의 메모리 블록 이 어디 에 있 는 지, Dumper 를 쓰 면 모두 얻 을 수 있다.암호 화 는 해 제 를 방지 할 수 없고 해 제 된 난이도 와 문턱 만 증가 할 뿐 암호 화 해 제 는 서로 게임 을 하 는 과정 이다.
자원 을 비밀 로 하면 기술 이 초보 적 이 고 간단하게 복사 하려 는 사람들 에 게 그들 은 너 를 어 쩔 수 없다.그러나 원 리 를 조금 알 고 IDA 를 조금 아 는 사람들 에 게 는 별 쓸모 가 없다.
좋아, 이제 연구 해 볼 게. 어떻게 조금 만 더 문턱 을 늘 릴 수 있 는 지.
이전에 복호화 의 중요 한 전 제 는 바로 디 버 깅 이 었 기 때문에 가장 직접적 으로 생각 하 는 증가 의 문턱 은 바로
이다.테스트
안 드 로 이 드 프로젝트 를 만 들 고 네 이 티 브 지원 을 추가 합 니 다.
android-anti-debug
먼저 pid 와 부모 pid 를 치고 나 와 보 겠 습 니 다.
#include <jni.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include "log.h"
void anti_debug()
{
int pid = getpid();
int ppid = getppid();
LOGD("pid:%d,ppid:%d",pid,ppid);
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
anti_debug();
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
{
return -1;
}
return JNI_VERSION_1_6;
}
06-11 06:42:24.411: D/[android-anti-debug](1451): pid:1451,ppid:192
pid 192 는:
root 192 1 492204 38400 ffffffff b756598c S zygote
Android 시스템 에서 모든 응용 프로그램 프로 세 스 와 시스템 서비스 프로 세 스 SystemServer 는 Zygote 프로 세 스 가 낳 은 (fork) 것 입 니 다. 이것 을 Zygote (수정란) 라 고 부 르 는 이유 일 수도 있 습 니 다.
구체 적 인 참조: Android 시스템 프로 세 스 Zygote 시작 과정의 소스 코드 분석
보다
/proc/1451/stat
root@mx3:/data/local/tmp # cat /proc/17204//status
Name: ndroidantidebug
State: S (sleeping)
Tgid: 17204
Pid: 17204
PPid: 2146
TracerPid: 0
Uid: 10058 10058 10058 10058
Gid: 10058 10058 10058 10058
FDSize: 256
...
gdbserver 로 attach 를 해서 무슨 일이 일 어 났 는 지 보 세 요.
root@mx3:/data/local/tmp # ps |grep blog
u0_a58 30678 2146 907884 59720 ffffffff 4005778c S com.zhaoxiaodan.blog.androidantidebug
root@mx3:/data/local/tmp # ./gdbserver --attach 127.0.0.1:1234 30678
Attached; pid = 30678
Listening on port 1234
root@mx3:/data/local/tmp # cat /proc/17204//status
Name: ndroidantidebug
State: t (tracing stop)
Tgid: 17204
Pid: 17204
PPid: 2146
TracerPid: 20337
Uid: 10058 10058 10058 10058
Gid: 10058 10058 10058 10058
발견
TracerPid
줄 이 0 에서 20337 로 바 뀌 었 습 니 다.ida 이러한 디 버 깅 도 구 는 모두
ptrace
를 사용 하여 진행 되 었 으 며, ptrace 는 매우 중요 한 특정 사항 이 있 습 니 다.하나의 프로 세 스 는 하나의 프로 세 스 에 의 해 디 버 깅 될 수 밖 에 없다.
그래서 가장 쉬 운 방법 은
JNI_OnLoad
에서 직접 ptrace(PTRACE_TRACEME, 0, 0, 0);
방법 1, 직접 ptrace(PTRACE_TRACEME, 0, 0, 0);
#include <jni.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include "log.h"
void anti_debug()
{
ptrace(PTRACE_TRACEME, 0, 0, 0);
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
anti_debug();
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
{
return -1;
}
return JNI_VERSION_1_6;
}
그리고 gdbserver 로 attach:
root@mx3:/data/local/tmp # ./gdbserver --attach 127.0.0.1:1234 31092
Cannot attach to lwp 31092: Operation not permitted (1)
Exiting
됐어, 끊 을 수가 없어.
그러나 이런 방법 은 역 컴 파일 로 열 면 호출
ptrace
된 곳 을 쉽게 찾 을 수 있 습 니 다. 수정
(예 를 들 어 Nilnil 로 바 꾸 는 것) 을 모 르 고 이 호출 을 건 너 뛰 었 습 니 다.방법 2, 어두 운 말뚝
위 에서 말 한
/proc/$pid/status
중 TracerPid
줄 에 디 버 깅 프로그램의 pid
원 리 를 표시 하 는 방법 을 써 서 이 값 을 검사 할 수 있 습 니 다. 만약! =0. 프로그램 종료검사 함 수 는 다음 과 같 습 니 다:
void be_attached_check()
{
try
{
const int bufsize = 1024;
char filename[bufsize];
char line[bufsize];
int pid = getpid();
sprintf(filename, "/proc/%d/status", pid);
FILE* fd = fopen(filename, "r");
if (fd != nullptr)
{
while (fgets(line, bufsize, fd))
{
if (strncmp(line, "TracerPid", 9) == 0)
{
int statue = atoi(&line[10]);
LOGD("%s", line);
if (statue != 0)
{
LOGD("be attached !! kill %d", pid);
fclose(fd);
int ret = kill(pid, SIGKILL);
}
break;
}
}
fclose(fd);
} else
{
LOGD("open %s fail...", filename);
}
} catch (...)
{
}
}
이 함 수 를 매크로 로 만 든 다음 에 프로그램 을 써 서 랜 덤 으로 이 매크로 를 소스 코드 의 각 곳 에 삽입 할 수 있 습 니 다. 코드 가 계속 실행 되면 서 이러한 검사 점 을 만 날 수 있 습 니 다.
사실 아무런 쓸모 도 없 는데, 단지 말뚝 이 많 을 뿐 이 니, 네가 뽑 으 면 좀 번 거 로 울 것 이다.
다음은 스 레 드 로 검사 과정 을 모 의 하 는 것 입 니 다.
#include "android-anti-debug.h"
#include <string>
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdlib.h>
#include <chrono>
#include <thread>
#include "log.h"
void be_attached_check()
{
try
{
const int bufsize = 1024;
char filename[bufsize];
char line[bufsize];
int pid = getpid();
sprintf(filename, "/proc/%d/status", pid);
FILE* fd = fopen(filename, "r");
if (fd != nullptr)
{
while (fgets(line, bufsize, fd))
{
if (strncmp(line, "TracerPid", 9) == 0)
{
int statue = atoi(&line[10]);
LOGD("%s", line);
if (statue != 0)
{
LOGD("be attached !! kill %d", pid);
fclose(fd);
int ret = kill(pid, SIGKILL);
}
break;
}
}
fclose(fd);
} else
{
LOGD("open %s fail...", filename);
}
} catch (...)
{
}
}
// ,
void thread_task(int n)
{
while (true)
{
LOGD("start be_attached_check...");
be_attached_check();
std::this_thread::sleep_for(std::chrono::seconds(n));
}
}
void anti_debug()
{
// ptrace(PTRACE_TRACEME, 0, 0, 0);
auto checkThread = std::thread(thread_task, 1);
checkThread.detach();
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
anti_debug();
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
{
return -1;
}
return JNI_VERSION_1_6;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.