Frida反调试

Frida反调试,第1张

逆向某app时,想用frida进行hook分析其执行流程,遇到了frida的反调试。这里记录一下出现问题的情况和反调试的实现.

Android8

frida12.11.18

windows10

使用frida -U注入app

结果如下

这里有两个com.shark.tracerpidapp名称的进程

我们直接进入adb查看进程

可以看到确实有两个进程,frida分不清你要注入哪个进程所以报出如上错误。

我们选择父进程进行注入

叫我们用root去执行,这里是没有用的。我们到adb看看这个父进程的TracerPid信息就知道了

至于为什么看TracerPid请移步文章 TracerPid反调试

可以看到父进程已经被子进程ATTACH,而frida也依赖于ptrace所以这里肯定注入不进去

我们不要让frida注入,而是使用frida启动app,使用-f选项,我们告诉Frida注入Zygote并开始启动应用程序

还有一种打补丁的方式,在下面参考中有。这里就不再赘述。

这个反调试其实就是用了 TracerPid反调试 的原理,但是在这里有一些不一样。

1:这里是子进程ATTACH父进程

2:在Android8中ptrace(PTRACE_TRACEME, 0, 0, 0)虽然返回的不是-1但是无法成功

所以我们这里要使用ptrace(PTRACE_ATTACH, parent, 0, 0)来实现。

PTRACE_ATTACH参数

ptrace(PTRACE_ATTACH,pid)

跟踪指定pid 进程。pid表示被跟踪进程。被跟踪进程将成为当前进程的子进程,并进入中止状态

PTRACE_CONT参数

ptrace(PTRACE_CONT, pid, 0, signal)

继续执行。pid表示被跟踪的子进程,signal为0则忽略引起调试进程中止的信号,若不为0则继续处理信号signal

先使用PTRACE_ATTACH进行附加,这时候被附加进程会阻塞。再使用PTRACE_CONT继续执行被附加的进程。为了确保PTRACE_CONT能被执行我们在PTRACE_ATTACH完后要马上wait阻塞当前线程。当附加成功后wait阻塞解除就能执行到PTRACE_CONT了

Android APP破解利器Frida之反调试对抗

ptrace使用简介

微软提供的API,随时在自己的程序中调用IsDebuggerPresent都可以检测出自己的程序是否被调试.

先在vc++ 6.0 创建一个控制台测试程序 代码如下:

#include <windows.h>

typedef BOOL ( _stdcall *LPAPI_IDP)(VOID)

int main(int argc, char* argv[])

{

HMODULE hModule = LoadLibrary("Kernel32") // 加载模块Kernel32

if (hModule == NULL)

{

ExitProcess(0) // 如果发现程序被调试 直接退出进程

}

LPAPI_IDP IsDebuggerPresent = GetProcAddress(hModule, "IsDebuggerPresent") // 获取下地址

if (IsDebuggerPresent == NULL)

{

ExitProcess(0) // 如果发现程序被调试 直接退出进程

}

if (*(BYTE *)IsDebuggerPresent == 0xcc || // 调用前检测下是否被下了断点

*(BYTE *)IsDebuggerPresent != 0x64 ||

IsDebuggerPresent()) // 调用

{

ExitProcess(0) // 如果发现程序被调试 直接退出进程

}

// 如果程序能执行到这里 说明程序没有被调试状态

MessageBox(NULL, "Antidebug", NULL, MB_OK)

return 0

}

按F5调试运行 就会发现 程序直接推出.

单步跟踪可以测试到调用IsDebuggerPresent以后程序退出.

1.程序窗口句柄检测

原理:用FindWindow函数查找具有相同窗口类名和标题的窗口,如果找到就说明有OD在运行

//********************************************

//通过查找窗口类名来实现检测OllyDBG

//********************************************

function AntiLoader():Boolean

const

OllyName='OLLYDBG'

var

Hwnd:Thandle

begin

Hwnd:=FindWindow(OllyName,nil)

if Hwnd<>0 then

Result:=True

else

Result:=False

end

procedure TForm1.FormCreate(Sender: TObject)

begin

if AntiLoader then

MessageBox(Handle,'找到调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未找到调试器!','提示',MB_OK+MB_ICONINFORMATION)

end

2.用线程环境块检测

原理:用ring3级下的调试器对可执行程序进行调试时,调试器会把被调试的可执行程序作为一个子线程进行跟踪.这时被调试的可执行程序的PEB结构偏移0x02处的BeingDebugged的值为1,如果可执行程序未被调试,则值为0,所以可以利用这个值来检测程序是否被ring3级下的调试器调试

//***************************************

//使用PEB结构检测OllyDBG

//***************************************

function AntiLoader():Boolean//检测调试器

var

YInt,NInt:Integer

begin

asm

mov eax,fs:[$30]

//获取PEB偏移2h处BeingDebugged的值

movzx eax,byte ptr[eax+$2]

or al,al

jz @No

jnz @Yes

@No:

mov NInt,1

@Yes:

Mov YInt,1

end

if YInt=1 then

Result:=True

if NInt=1 then

Result:=False

end

procedure TForm1.FormCreate(Sender: TObject)

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

end

3.用API函数IsDebuggerPresent检测

原理: *** 作系统将调试对象设置为在特殊环境中运行,而kernel32.dll中的API函数IsDebuggerPresent的功能是用于判断进程是否处于调试环境中,这样就可以利用这个API函数来查看进程是否在调试器中执行

//****************************************

//利用IsDebuggerPresent函数检测OllyDBG

//****************************************

function AntiLoader():Boolean

var

isDebuggerPresent: function:Boolean

Addr: THandle

begin

Addr := LoadLibrary('kernel32.dll')

isDebuggerPresent := GetProcAddress(Addr, 'IsDebuggerPresent')

if isDebuggerPresent then

Result:=True

else

Result:=False

end

procedure TForm1.FormCreate(Sender: TObject)

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未发现提示器!','提示',MB_OK+MB_ICONINFORMATION)

end

4.检查程序的父进程

原理:Windows *** 作系统下的GUI可执行程序的父进程都是explorer.exe(CUI可执行程序的父进程是CMD.exe,系统服务的父进程是Service.exe,在实际使用的时候需要根据自己的程序类型来选择父进程实现反跟踪),而正被调试器OD调试的程序的父进程是调试器的执行程序ollydbg.exe而不是别的.所以可以利用检查父进程是否为explorer.exe的方法来检测OD.

//***************************************************

//检查父进程来检测OllyDBG

//***************************************************

function AntiLoader():Boolean

const

ParentName='\EXPLORER.EXE'

var

hSnap,hProcess:THandle

szBuffer:array[0..MAX_PATH] of char

FileName:array[0..MAX_PATH] of char

Process32:PROCESSENTRY32

LoopFlag:BOOL

begin

////得到所有进程的列表快照

hSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)

if hSnap=INVALID_HANDLE_VALUE then

begin

Result:=False

Exit

end

Process32.dwSize:=sizeof(PROCESSENTRY32)

//查找进程

LoopFlag:=Process32First(hSnap,Process32)

if LoopFlag=False then

begin

CloseHandle(hSnap)

Result:=False

Exit

end

while Integer(LoopFlag)<>0 do

begin

if Process32.th32ProcessID=GetCurrentProcessId() then

begin

hProcess:=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Process32.th32ParentProcessID)

if hProcess<>0 then

begin

if GetModuleFileNameEx(hProcess,0,FileName,MAX_PATH)<>0 then

begin

//取得系统目录

GetWindowsDirectory(szBuffer,MAX_PATH)

//合并系统目录和\EXPLORER.EXE

StrCat(szBuffer,ParentName)

//转换成大写以后比较当前调试程序的进程是否为父进程

if UpperCase(String(FileName))<>UpperCase(String(szBuffer)) then

Result:=True

else

Result:=False

end

end

else

Result:=False

end

LoopFlag:=Process32Next(hSnap,Process32)

end

CloseHandle(hSnap)

end

procedure TForm1.FormCreate(Sender: TObject)

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

end

5.检查STARTUPINFO结构

原理:Windows *** 作系统中的explorer.exe创建进程的时候会把STARTUPINFO结构中的值设为0,而非explorer.exe创建进程的时候会忽略这个结构中的值,也就是结构中的值不为0,所以可以利用这个来判断OD是否在调试程序.

/************************************************

//通过检测STARTUPINFO结构来检测OllyDbg

//************************************************

function AntiLoader():Boolean

var

Info:STARTUPINFO

begin

GetStartupInfo(Info)

if (Info.dwX<>0) or (Info.dwY<>0) or (Info.dwXCountChars<>0) or (Info.dwYCountChars<>0) or

(Info.dwFillAttribute<>0) or (Info.dwXSize<>0) or (Info.dwYSize<>0) then

Result:=True

else

Result:=False

end

procedure TMainFrm.FormCreate(Sender: TObject)

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK)

else

MessageBox(Handle,'未发现调试器!','提示',MB_OK)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8043530.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-12
下一篇 2023-04-12

发表评论

登录后才能评论

评论列表(0条)

保存