击败调试器

使用FCEUX调试器修改FC游戏初始物品:逆向工程入门实践 在计算机系统中,程序运行时数据主要存储在RAM(随机存取存储器)中,其地址映射与读写机制是理解软件运行原理的基础。通过内存地址访问与修改,可以动态改变程序状态,这是调试、逆向工程与游戏修改的核心技术之一。FCEUX作为一款集成了强大调试功能的FC模拟器,提供了实时内存查看、断点设置与反汇编等工具,使得分析8位游戏内存结构成为可能。其内存搜索功能(如差值搜索法)能有效定位存储物品数量、生命值等关键变量的RAM地址,进而实现运行时状态修改。这种实践不仅有助于理解数据存储与程序交互的底层逻辑,也为学习软件逆向、漏 阅读详情

转载至 http://blog.youkuaiyun.com/excuseser/archive/2005/05/06/372762.aspx

[出处]http://www.osix.net/modules/article/?id=594
[说明]第一篇是胡乱的译,胡乱的贴上去的,竟......啥也不说了,
感谢kanxue老大的lift和linhanshi大哥的encourage.
为此又贴一篇,
同样简单,但因为我是个新手,译得肯定有很多漏洞和争议,因此严重希望博得大伙窃笑的同时,
别忘了批我,帮助我提高:). 

[译者]aalloverred

[译文]

击败调试器

这次我们看看如何使别人跟踪你的代码变得困难,将要学习的是调试器相关知识,它们是如何工作
的,及你的程序如何检测到它们.

-----------------------
躲避调试器-保护你的程序
-----------------------
作者 Giovanni Tropeano 于11/2004
为 OSIX 而作

<<文章目录<<

...前言
...调试器简史
...调试器是如何工作的
...跟踪,及如何战胜它
...躲过断点

:::前言:::

以下面这句话作为开始--
引用:
/你不可能也不会编出无法被破解的程序./
但这并不是说不能将此变得非常非常困难.

闲言少叙,书归正传.本文中,我们将要学习一些反调试技巧,你可以将它们用于你自己的程序中.

我为OSIX写的第一篇文章中讨论了自修改代码,并试图摆脱调试器.现在要讨论的是击败(或至少是
其变得困难)调试器.

:::调试器简史:::

以前有一个Debug.com,它是第一个Windows调试器.它属于标准MS-DOS包中的一部分,而今天除了用
于学习汇编很少有其他用途了.勉强适合破解用的调试器最早是随80286出现的,但它们不能造成什
么实际的伤害.

但是,80386出现后情况有了变化,主要的复杂情况是软件(Windows?)需要更好的调试器.就是这个时
候,随着一些调试器的不断强大,它们开始成为程序员的威胁.80年代末期,Softice出现在舞台上,给受
保护程序及它们的开发者带来不少的麻烦.从那时候起,Softice就作为黑客调试工具传了下来.但最近
Olly在年轻一代破解者中越来越常用.

现在由于分析软件的可能性,与黑客对抗就成了无用的挣扎.而与此同时还有威胁来自于那些原本是
新手,但读过了许多"如何破解程序"问题集后(幸运的是每个人都可以得到这些东西),现在正在寻找
一些东西要来练练手的人.我们想要摆脱的就是这些在寻找新的挑战的新手.

:::调试器如何工作::: 

不知道调试器如何工作就要对抗它会是空谈.因此理解调试器究竟是如何工作的很重要.

所有的调试器都无非属于下面两类:

.使用处理器的调试能力
.独立的模仿处理器,监视被测试程序的运行

迄今还没有高水平的可以不被代码检测到或者避过代码的检测的模仿型的调试器,而且现在看来在
未来的一段时间内也不会出现.

关键是,开发这样一个仿真器值得么?因为我们已经能够步入代码,控制某个地址的指令的执行,监视
某个内存地址(或输入输出端口)的指向,改变信号任务,等等.我认为不值得.不管怎样,继续下去...

好,下面将要进行深入点的研究,试着跟上.

调试器会检查标志寄存器的陷阱位是否为1.如果是,就在每条指令后自动生成一个INT 1 调试异常,
并且将控制权交给调试器.由此可知,代码可以通过分析标志寄存器来检测跟踪(调试).所以调试器为
了不被发现,它必须识别出读取标志寄存器的指令,模仿其运行,并且为陷阱标志返回零.说起来容易
做起来难,是吧?

有四个调试寄存器:

1. DR0 
2. DR1 
3. DR2 
4. DR3 

它们存储了四个检测点的线性地址.当然还有一个寄存器保存了每个点的条件,它就是DR7.当任何
一个条件为真时,处理器就会抛出INT1异常,控制权也就交给了调试器,有四个条件:

1.一条指令被执行
2.某个内存地址的内容被改变了
3.某个内存地址被读取或改变,但没有被执行
4.一个输入输出端口被引用

现在要讨论的是软件断点.软件断点是唯一只有用处理器的完全仿真器才能被隐藏的东西.如果将一
个字节的代码--0xCC插入到一条指令前,再试图执行它就会引发INT 0x3异常.为了发现是否至少有一
个点被设置了断点,程序仅需计算其校验和就可以了.为了做到这一点,可以使用MOV, MOVS, LODS, 
POP, CMP, CMPS或其他任何指令;没有任何调试器能够跟踪模仿其中的任何一个(据我所知!).


:::跟踪,以及如何战胜它::: 

因为完全不可见的调试器还仅仅是一种"可能",大部分还都是可以被检测到的.
大部分调试器使用一字节的0xCC代码.

让我们看一个简单的保护方法:

列表1.C++中一种简单的保护方案

int main(int argc, char* argv[]) 
{ 
// 加密后的字符串 "Hello, Free World!" 
char s0[]="/x0C/x21/x28/x28/x2B/x68/x64/x02/x36/ 
/x21/x21/x64/x13/x2B/x36/x28/x20/x65/x49/x4E"; 
__asm 
{ 
BeginCode: ; 正在被调试的
                                  ;  代码的开始 

        pusha ; 所有的通用 
                                  ; 寄存器都被保护起来. 
        lea ebx, s0 ; ebx=&s0[0] 
GetNextChar: ; 开始 
         xor eax, eax ; eax = 0; 
         lea esi, BeginCode ; esi = &BeginCode 
         lea ecx, EndCode ; 代码的长度 
         sub ecx, esi ; "正在被调试"也被计算在内 
         HarvestCRC: ; 计算
         lodsb ; 下一字节载入到al. 
         Add eax, eax ; 计算校验和. 
         loop HarvestCRC ; 直到(--cx>0) 
         xor [ebx], ah ; 下一个字符被解密. 
         Inc ebx ; 指向下个字符的指针 
         cmp [ebx], 0 ; 直到字符串结束 
         jnz GetNextChar ; 继续解密 
         popa ; 恢复所有的寄存器. 
EndCode: ; 被调试代码的结尾 
         nop ; 这里的断点是安全的. 
} 
printf(I s0); ; 显示字符串. 
return 0; 
} 

仔细看看这段代码(注意注释).程序启动后,句子"Hello,Free World!"将会出现在屏幕上.但是当它运行
在调试器下时,哪怕只有一个断点设置在了BeginCode和EndCode之间,一些像"Jgnnm."Dpgg"Umpnf#0"
这样毫无意义的垃圾信息就会出现在屏幕上.不赖,是么?现在才有些到了点子上了.你甚至可以把计
算校验和的过程放在另一个线程中来加强这种保护.

说到线程,它需要对事物使用专门的方法.对我们这些凡人来说,要实现同时运行在几个地方的程序
有点难.而常用的调试器都有一个弱点,即它们是分别调试每个进程的,从来不同时调试.下面的例
子演示了如何将此用于保护.

表2 . 分别地调试线程的弱点

// 这个函数将要在另外一个线程内执行. 
// 它的作用是神不知鬼不觉地改变用户名字符串中字符的大小写 .

void My(void *arg) 
{ 
      int p=1; 
      // 这个指针指向正在加密的字节. 
      // 注意加密并没有从第一个字节开始执行,
      //因为那样的话,断点就能设在缓存的开始
      //而躲过检测.         
      //如果碰到的不是换行符'/n'就执行. 
      while ( ((char *) arg) [p] !='/n') 
      { 
            // 下一个字符是否未被初始化?   同时也是在等待. 
            while( ((char *) arg) [p]<0x20 ); 

            // 第五位发生翻转. 
            // 这也就转换了拉丁字符的大小写. 
            ((char *) arg) [p] ^=0x20; 

            // 指向将被处理的下一个字节. 
            p++; 
      } 
} 

int main(int argc, char* argv[]) 
{ 
      char name[100]; 
      //存储用户名的缓存 

      char buff[100]; 
      //存储密码的缓存

      //用户名缓存中填充0. 
      // (有的编译器会这样做,但并不是所有的.) 
      memset (&name[0], 0, 100); 

      //子程序My在另外一个线程里执行. 
      _beginthread(&My, NULL, (void *) &name[0]); 

      //需要输入用户名. 
      printf("Enter name:"); fgets(&name[0], 66, stdin); 

      //需要输入密码. 
      //注意: 用户输入密码的过程中, 第二线程有充分的时间
      // 将用户名中所有字符转换大小写.这很隐蔽,对程序的分析也不会
      // 跟踪至此.在一个不善于反应程序各部分间的影响的调试器下
      // 调试时尤其如此. 
 
      printf("Enter password:"); fgets(&buff[0], 66, stdin); 

      // 用户名和密码通参考值作比较. 
      //  
      if (! (strcmp(&buff[0], "password/n") 
      //注意: 因为输入的用户名被改变了,所以 
      //用strcmp(&name[0], "Osix/n"), 
      //而不是strcmp(&name[0], "OSIX/n")来比较它. 
      // (这乍一看时很不明显.) 

      || strcmp(&name[0], "OSIX/n"))) 
      // 正确的用户名和密码 
      printf("USER OK/n"); 
             else 
      // 错误:错误的用户名或密码 
      printf("Wrong user or password!/n"); 

      return 0; 
} 

看一下列表中的程序,我们关心是程序看来要接受OSIX:password的, 但实际的答案却
是Osix:password.我们来研究的稍微仔细些.用户输入用户名后,第二个线程就处理存有用
户名的缓存,并且转换了大小写(除了第一个字符).所以就知道了,当一个线程被调试的
时候,所有其他线程都在各自独立的工作着.而这些其他线程也可以随意的干涉正在被调
试的线程的工作(比如说更改它的代码).啊...到现在这才开始有些可能了!

这里又有一些东西得考虑了.因为已经知道线程可以被控制,但是如果保护开发者放置了
多于四个的断点,调试寄存器就不再可信了,我们就不得不使用0xCC字节,而这样做的话,由上文
可知是很容易被检测到的.

若是被调试的程序里使用了结构化异常处理(structural exception handling ,SEH ),调试器就会把
情况搞得更糟,著名的Softice也不例外.那样正在被调试的指令要么会"击败"调试器,将自己
由调试器的控制中释放出来,要么将控制权交给库异常,而它只不过是在调用几个代码足以淹没
破解者的服务程序之后将控制权交给程序处理.

然而,与以前的Softice版本相比,这种情况有了进步.以前,Softice严格控制某些中断,比如它
不允许程序独立执行除零的操作.

让我们再看看另外一些代码吧?!当下面的例子在Softice 包括4.05及以下的任何版本下运行,调试
器到达行int c=c/ (a-b)时都将会突然中止执行,失去对程序的控制权.但是这种情况可以得到
改正,只要提前在__except块的第一条指令处设置断点即可.那么问题是如何如不用深入源代
码就找到这个块的位置呢?而黑客是不可能有源代码的.

列表3. 使用结构化异常处理(structural exception handling)的一个例子
int main(int argc, char* argv[]) 
{ 

// 受保护的块 
__try{ 
         int a=1; 
         int b=1; 
         int c=c/ (a-b); 
         // 这里是做执行除零的操作. 
         // 使用了多条指令是因为 
         // 大部分编译器遇到形如
         // int a=a/0的表达时都会返回错误; 
         // 当SoftIce执行下面的指令时, 它就失去了 
         // 对被调试程序的控制权. 它落到了一些 
         // 从不会获得控制权却可能产生误导的代码上. 
         // 如果变量a和b被赋予的是某些函数的返回值,
         // 而不是立即数, 二者的相等的关系
         // 在程序被反汇编了之后 
         // 就不那么明显了. 结果就是, 黑客可能会浪费时间
         // 去分析那些无用的代码 ,嘿嘿呵! 
} 

__except(EXCEPTION_EXECUTE_HANDLER) 
{ 
         // 发生除数为零的异常时,这里的代码将会获得 
         // 控制权 , 但是SoftIce意识不到这种情况。 
         // 取而代之,要求手动在__except块的第一条指令
         // 处设置断点 . 
         // 要确定块__except的地址, 黑客必须准确地指出
         // SEH支持是如何在某个特定的 
         // 编译器中实现的. 
} 
} 

对于破解者来说,他们处理这样的保护时必须深入的研究结构化异常在系统级别上和在调试器级别
上是如何进行的.对于一个业余的破解者来说工作量太大了,不是么?

因为SEH在不同的编译器中实现方法是不同的,这也就难怪SoftIce不支持它了.这对程序员来说是
好事,对破解者来说就太糟糕了!

所以前面的例子都是强烈对抗中断的,同时也容易实现.它在从Windows95开始的Windows家族的所
有操作系统下都能很好的起作用.

:::躲过断点::: 

在系统函数上下断点是破解者拥有的强大武器.假设某个保护试图打开key文件.在Windows下,唯一
一个在文献中记录着的做法就是调用CreateFile函数(实际上,CreateFileA和CreateFileW是分别对应文件
名的ASCII和UNICODE形式而已). 所有其他由早期的Windows版本继承而来的函数都只不过是封装
了CreateFile而已.

知道了这些,黑客就会在函数开始的起始地址设置断点(这个地址黑客是知道的),从而迅速的定位调

用了这个函数的保护代码.

尽管如此,并不是所有的黑客都知道打开文件可以有另外的方法:通过调用由NTDLL.DLL输出的

ZwCreateFile (或者NtCreateFile)函数,或者通过调用INT 0x2Eh中断直接定位kernel.这不仅仅对CreateFile
成立,kernel中的所有函数都是这样的.还有有用一点是做到这些不需要什么权限.这样的调用甚至可

以是源于程序代码的.

这些小把戏不会阻止破解者太长时间.这很糟糕.但是将这个小定时炸弹放在那里是值得的(在块

__try中调用INT 0x2E中断).

现在,怎么处理USER和GDI模块中那些用来读取用户输入的注册信息(按惯例,是一个序列号或者密
码)的函数(比如,GetWindowsText)呢?因为我们知道这些函数都是以指令PUSH EBP/MOV EBP, ESP开
始的,指令代码可以另外的执行它:即不将控制权直接的传到函数开始,而是开始处三个字节后(因为
PUSH EBP会改变堆栈,传递控制权时必须使用JMP而不是CALL.)这样设置在函数开始出的断点就不
会产生任何作用.这样的技巧可能会使一个熟练的黑客都暂时的误入歧途.

断点可被分为两类:开发者设置在程序内的断点和调试器本身设置的动态断点.第一类很清楚:要将
控制权在某个必要的地方转移给调试器就必须使用__asm{int 0x3}. 

在程序的任意位置设置的断点就有些复杂了.调试器会保存指定位置处内存地址的当前值,然后再
在那里写入代码0xCC.退出调试中断之前调试器会将全部位置都恢复原样,并修改堆栈中存储的IP
的值使其指向已恢复的指令的开始处.(否则,它就会指向它的中间.)

图1:进入中断子程序时堆栈的内容
--------
8086处理器的断点机制的缺点是什么呢?最让人感觉不好的就是调试器设置断点时必须直接修改代
码.

SoftIce中使用步过(F10键)方式跟踪程序时只是隐式的将断点设在下一条指令的前面,这样就会破
坏保护代码中用到的校验和.

最简单的解决方法是一条指令一条指令的跟踪--当然,这是在说笑;这种情况必须设置硬件断点.碰到

类似的情况时,我们的前辈们(1980年代的黑客)通常都是手动将程序解密,再结合NOP指令将解密过

程替换掉.这样,调试程序时就不会再出现问题了(如果保护中没有使用其它陷阱的话).在IDA出现以

前,解密程序都是作为一个独立的程序在C(Pascal,BASIC)中编制的.现在这项工作已经变得简单了,因

为解密在反汇编器内部实现已经成为了可能.

解密实际上就是用IDA-C语言对解密程序重新编制.这种情况下,从BeginCode到EndCode的校验和必
须计算出来,算上每个字节的和再用校验和的低字节载入下一个字符.获得的值用来使用异或操作
处理s0字符串.所有这些都可以使用下面的代码实现(假设反汇编代码中已经存在了适当的标签):

列表 239. 用IDA-C重新实现解密功能

auto a; auto p; auto crc; auto ch; 
for (p=LocByName("s0"); Byte(p) !=0; p++) 
{ 
      crc = 0; 

      for(a=LocByName("BeginCode"); a<(LocByName("EndCode")); a++) 
      { 
            ch = Byte(a); 
            // 因为IDA不支持byte和word类型 
            // (是个遗憾), 必须让它参与位运算. 
            //  CRC低字节被清除, 
            //然后CH的内容拷贝到那里. 

            crc = crc & 0xFFFFFF00; 
            crc = crc | ch; 
            crc=crc+crc; 
      } 
      //从CRC中取出高字节. 
      crc = crc & 0xFFFF; 
      crc = crc / 0x100; 

      // 字符串的下一个字节被解密. 
      PatchByte(p, Byte(p) ^ crc); 
} 


如果没有IDA,在HIEW中也可以实现这个过程,如下:

 NoTrace.exe ?W PE 00001040 a32 <Editor> 28672 ? Hiew 6.04 (c)SEN 
00401003: 83EC18 sub esp, 018 ;"$" 
00401006: 53 push ebx 
00401007: 56 push esi 
00401008: 57 push edi 
00401009: B905000000 000005 
0040100E: BE30604000 [Byte/Forward ] 406030 ;" @'0" 
00401013: 8D7DE8 1>mov bl, al | AX=0061 p][-0018] 
00401016: F3A5 2 add ebx, ebx | BX=44C2 
00401018: A4 3 | CX=0000 
run from here: 4 | DX=0000 
00401019: 6660 5 | SI=0000 [0FFFFFFE8] 
0040101B: 8D9DE8FFFF 6 | DI=0000 
00401021: 33C0 
.0040101B: 8D9DE8FFFFFF 
.00401021: 33C0 xor eax, eax 
.00401023: 8D3519104000 lea esi, [000401019]; < BeginCode 
.00401029: 8D0D40104000 lea ecx, [000401040]; < EndCode 
.0040102F: 2BCE sub ecx, esi 
.00401031: AC lodsb 
00401032: 03C0 add eax, eax 
00401034: E2FB loop 000001031 
00401036: 3023 xor [ebx], ah 
00401038: 43 inc ebx 
00401039: 803B00 cmp b, [ebx], 000 ;" " 
0040103C: 75E3 jne 000001021 
0040103E: 6661 popa 
to here: 
00401040: 90 nop 
00401041: 8D45E8 lea eax, [ebp][-0018] 
00401044: 50 push eax 
00401045: E80C000000 call 000001056 
0040104A: 83C404 add esp, 004 
1Help 2Size 3Direct 4Clear 5ClrReg 6 7Exit 8 9Store 10Load 

第一步,计算校验和.文件载入HIEW后,要找到所需的代码片断.然后按两次<Enter>键将其转换到汇编

模式,在按下组合键<F8>+<F5>跳到入口点,这就找到了开始代码主过程.下一步,按<F3>键进入文
件编辑状态,用组合键<Ctrl>+<F7>调出解密编辑窗口(这个组合键随着版本的不同而不同).然后输入
下面的代码:

mov bl, al 
add ebx, ebx 

可以用其他的寄存器代替EBX,但是不能用EAX,因为HIEW每次读取下一个字节前都会将EAX清除.
现在鼠标到了0x401019这一行,按<F7>键运行解密过程到0x401040这一行(但不包括这行).如果这些都
作的没错的话,高字节BX中的值0x44正是校验和.

第二步里,找到的加密行(它的偏移,载入了ESI),然后与0x44异或.(按<F3> 键转到编辑模式,按
<Ctrl>+<F8> 键指定加密用的key, 0x44, 再按 <F8>键按行执行解密程序.) 

NoTrace.exe ?W PE 00006040 <Editor> 28672 ? Hiew 6.04 (c)SEN 
00006030: 48 65 6C 6C-6F 2C 20 46-72 65 65 20-57 6F 72 6C Hello, Free World 
00006040: 20 65 49 4E-00 00 00 00-7A 1B 40 00-01 00 00 00 eIN z$@ $ 

现在剩下的就是将行0x401036处的XOR用NOP指令换掉,否则程序运行时,XOR会破坏解密代码(会再
加密一次),程序也就不再工作了.

去除了这个保护后,再调试这个程序时,在需要的范围内就不会产生严重的后果了.

好了,到此为止了.又一篇关于汇编和调试的文章,很长,但希望还算有用.

再见!

Trope

CTF-PWN练习 目录预备知识了解CTFLinux管道Python基础gdb调试器汇编基础实验目的实验环境实验步骤一源码审计实验步骤二使用gdb调试程序实验步骤三体验溢出攻击效果 预备知识 了解CTF CTF的全称是Capture The Flag,即夺旗的意思,因此CTF比赛也称为夺旗比赛。CTF夺旗赛是计算机安全竞赛的一种形式,CTF比赛主要表现以下几个技能上:逆向工程、密码学、ACM编程、Web漏洞、二进制溢出、网络和取证等。在国际CTF赛事中,二进制溢出也称之为PWN。 PWN是一个黑客语法的俚语词,自“own”这个 阅读详情

相关推荐

CTF-记一次PWN练习

在CTF中PWN题型通常会直接给定一个已经编译好的二进制程序(Windows下的EXE或者Linux下的ELF文件等),然后参赛选手通过对二进制程序进行逆向分析和调试来找到利用漏洞,并编写利用代码,通过远程代码执行来达到溢出攻击的效果,最终拿到目标机器的shell夺取flag。try again.的提示信息,请对pwn1程序进行逆向分析和调试,找到程序内部的漏洞,并构造特殊的输入数据,使之输出Congratulations,

小王的技术库 1266

击败调试器[zt]

[出处]http://www.osix.net/modules/article/?id=594[说明]第一篇是胡乱的译,胡乱的贴上去的,竟......啥也不说了,感谢kanxue老大的lift和linhanshi大哥的encourage.为此又贴一篇,同样简单,但因为我是个新手,译得肯定有很多漏洞和争议,因此严重希望博得大伙窃笑的同时,别忘了批我,帮助我提高:). [译者]aalloverred[

excuseser的专栏 1923

CTF | PWN练习一

预备知识: 1、了解PWN(溢出) PWN是一个黑客语法的俚语词,自"own"这个字引申出来的,这个词的含意在于,玩家在整个游戏对战中处在胜利的优势,或是说明竞争对手处在完全惨败的 情形下,这个词习惯上在网络游戏文化主要用于嘲笑竞争对手在整个游戏对战中已经完全被击败(例如:"You just got pwned!")。有一个非常著名的国际赛事叫做Pwn2Own,相信你现在已经能够...

qq_42646885的博客 2404

Unity debugger detected e0030 sentinel ldk protection system

工作的时候,遇到了一个很恶心人的事情,用Unity调试其C++的DLL时候,出现了下图这样的提示: 然后Unity的exe就莫名其妙退出了? 这样我就调试不了我的DLL了,这个问题折磨了我大概快一个月了,上谷歌上也查不到这个问题怎么解决,后来得知Sentinel LDK Protection System是Unity专门为在中国区下载Unity加的内容!! 估计是为了防止国人破解把。。。。。。。...

alexhu2010q的博客 7291

一文看懂分布式存储架构

目录一、集中存储结构二、分布式存储1 、分布式存储的兴起2 、分布式存储的重要性3 、分布式存储的种类和比较三、分布式理论浅析1 、一致性和可用性2 、数据分布3 、复制4 、分布式协议5、跨机房部署四、分布式文件系统1、 Google 文件系统( GFS )2、 Taobao 文件系统( TFS )3、 Fackbook Haystack 文件系统4、 CDN 内容分发网络五、分布式键值系统1、 Amazon Dynamo2、 Taobao Tiar3、 ETCD4 、产品选型比较( Etcd , Zoo

weixin_70730532的博客 2万+

F5高可用HA配置详情

F5 HA详细配置

weixin_45843944的博客 3026

软件保护壳技术专题 - 反调试器技术

 作 者: 玩命时 间: 2008-08-21,10:38链 接: http://bbs.pediy.com/showthread.php?t=71113反调试是软件保护壳的最基本的功能之一。反调试方法也是多种多样。通过调用标准的API接口,计算指令时间差。查看当调试器加载后的内存的一些标志,还有就是判断当前运行环境是否合乎逻辑等方法。这里收集了一些反调试的方法,其中的命名规则使用了壳狼的反调试程

4992

RAG系统中Embedding模型选型实战

本文详细介绍了RAG系统中Embedding模型选型实战,希望能对学习RAG的同学们有所帮助。 文章目录 1. 前言 2. 思路解析 3. 测评数据集构建 3.1 步骤一 3.2 步骤二 3.3 数据示例 3.4 总结 4. 实战代码 4.1 本地模型 4.2 使用第三方的Embedding模型API

herosunly的博客 17万+

脱壳入门(八)之带反调试的加密壳

文章目录程序分析分析过程1.找OEP2.反反调试3.解密IAT4.OD脚本还原IAT5.内存重建IAT表6.Dump文件,修复 程序分析 查壳:PESpin壳,连接器版本也没有 分析过程 1.找OEP 用OD载入文件,F7单步走几步就可以看到pushad,用ESP定律 程序直接运行完毕,并没有断下来,这说明这个壳有清除硬件断点的反调试 得换条路,下API断点,常见的入口API VB程序:Ge...

w_g3366的博客 1422

【深度学习新浪潮】李飞飞团队VAGEN框架深度解析:让VLM智能体学会“三思而后行“

VAGEN框架的真正价值,不仅在于性能指标的突破,更在于重新定义了VLM智能体的发展方向——人工智能的进步不应只追求"做得对",更要实现"想得清"。李飞飞团队通过强制显式思考、动态表示适配和精细化奖励三大创新,让智能体第一次具备了可解释的世界建模能力。正如人类通过"观察-预测-行动"认识世界,VAGEN为AI注入的这种思考范式,或许正是通往通用人工智能的关键一步。对于开发者而言,开源的VAGEN框架不仅提供了强大的工具,更揭示了一个重要理念:让AI学会思考,比让它学会执行更重要。

专注:太空算力、AI infra、异构调度、大模型成本工程 281

Realtek千兆PHY RTL8211FS相关寄存器操作详解

通过合理配置和控制RTL8211FS寄存器,您可以实现对以太网的各种功能和参数的控制和配置。请注意,具体的寄存器操作和配置值可能因具体需求而有所不同,您应参考RTL8211FS芯片的数据手册以获取准确的寄存器说明和操作规范。我们将提供相应的源代码示例,以帮助您理解和实施这些操作。通过操作这些寄存器,我们可以配置和控制RTL8211FS芯片的各种功能和参数。需要注意的是,具体的寄存器操作和配置值会根据您的具体需求而有所不同。您需要参考RTL8211FS芯片的数据手册以获取详细的寄存器说明和操作规范。

RlDart的博客 2661

使用Nemiver调试器来调试 C/C++ 程序

使用Nemiver调试器来调试 C/C++ 程序 如果你读过我写的使用GDB命令行调试器调试C/C++程序,你就会明白一个调试器对一段C/C++程序来说有多么的重要和有用。然而,如果一个像GDB这样的命令行对你而言听起来更像一个问题而不是一个解决方案的话,那么你也许会对Nemiver更感兴趣。Nemiver是一款基于 GTK+ 的用于C/C++程序的...

weixin_34235371的博客 319

Simulink开发项1000例实战专栏--实例52:基于Simulink开发一个超导磁储能控制系统,实现对SMES系统的精确控制和优化

需求分析超导磁储能系统(Superconducting Magnetic Energy Storage, SMES)是一种利用超导线圈储存和释放电能的高效储能技术。SMES系统具有响应速度快、能量密度高、循环寿命长等优点,广泛应用于电力系统的调峰填谷、频率调节、电压稳定以及紧急备用电源等领域。本项目将基于Simulink平台,开发一个完整的超导磁储能控制系统,实现对SMES系统的精确控制和优化。我们将详细讲解如何设计和实现该系统,并结合实际应用案例进行说明。

xiaoheshang_123的博客 237

CTF-PWN练习 ——合天网安实验室学习笔记

实验链接 PWN是CTF竞赛中的主要题型之一,主要考查参赛选手的逆向分析、漏洞挖掘以及Exploit编写能力。CTF-PWN系列实验以最常见的栈溢出为主线,通过由浅入深的方式,一步一步讲解栈溢出攻击原理与实践,同时详细介绍了Linux下GDB调试器的基本使用方法。 链接:http://www.hetianlab.com/expc.do?ce=718575ff-459f-4cc0-8099-e7f4...

weixin_42582241的博客 1743

移花接木,玩转CANoe的几种扩展接口应用(五)——串口设备

近期看到粉丝朋友在CANoe自动化测试方面的关注度很大,今天就围绕这个做一个专题,总结一下以往项目上用过的几种CANoe扩展接口,分享出来希望对相关领域的网友有所帮助。本文是该专题的第五篇文章,主要讲解了串口设备的功能配置、连接方法、配置方法、调用方法,最后分析了这种扩展借口应用的特点和适用场景。

Mr.Cssust的博客 2371

点云目标检测:open3d多窗口联动可视化

多个模型之间的对比除了指标之外,还需要可以直接直观的对比可视化结果,这次介绍一下如何使用open3d同时打开两个窗口分别加载两个模型的结果进行对比,同时实现两个窗口的联动,也就是当一个窗口拖动或者缩放时另外一个窗口也跟着做同样的变换。

zhaoguanhua的博客 4688

斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)

来到帝都米特尔拍卖行的萧炎,在雅妃姐的帮助下,来到了拍卖行的内屋,但是色鬼雷勒的出现打扰了本该祥和的气氛,萧炎不忍雅妃姐受此侮辱,三拳两脚便将雷勒击败。而没过多久,雷勒搬出自己的爷爷想要教训萧炎,真实鸡窝出不了金凤凰,雷欧虽贵为长老但德行也是极差,不分青红皂白就要收拾萧炎,还好海老在场,一招便使得雷家乖乖听话,束手就擒。在这三年里,萧炎得到过也失去过,这些经历让萧炎逐渐成长,帝都即将迎来新的传奇。斗气有十一个阶别,斗之气,斗者,斗师,大斗师,斗灵,斗王,斗皇,斗宗,斗尊,斗圣,斗帝。“也”可以用also。

南北粉面馆 839

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

gdb java,调用gdb来调试java程序

错误没有这样的文件或目录,gdb如果错误消息来自emacs,则表示未安装 gdb . 要解决此问题,请安装 gdb . 请注意 gdb 不是emacs的一部分,它是一个单独的程序 . 如果你得到一个包的 gdb ,它通常是 gcc ,GNU编译器集合的一部分,而不是Emacs . 来源是相同的 - FSF(自由软件基金会)/ GNU项目(GNU不是Unix),但它是不同的/单独的包 .如果错...

weixin_36485298的博客 782

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【Linux操作系统】基础开发工具

本文介绍了Linux开发中的常用工具链,包括软件包管理(yum/apt)、文本编辑器(Vim)、编译器(gcc/g++)、构建工具(make/Makefile)、进度条实现、版本控制(Git)和调试器(gdb/cgdb)。重点讲解了Vim的多模式编辑、gcc的编译流程与动静态链接区别、Makefile的自动化构建原理,以及Git的版本控制三板斧操作。这些工具构成了Linux环境下高效开发的完整工作流,帮助开发者完成从代码编写、编译构建到版本管理的全流程工作。

2401_82610555的博客 4210

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C# 夺冠!23 年来,首次荣获 TIOBE 年度编程语言

作者 | 苏宓出品 | 优快云(ID:优快云news)2024 年伊始,TIOBE 最新的 1 月榜单重磅发布,快来看看有哪些变化吧!C#摘得 2023 年编程语言称号!上个月,TIOBE 官方曾做出了一个大胆的预测,即从未获得此称号的 C#,正走在成为 2023 年度编程语言的路上。随着最新一期的榜单的发布,预测成真,C# 首次荣获年度编程语言奖。对此,TIOBE 软件公司首席执行官Pa...

优快云资讯 7966

暗黑破坏神2重制版自动刷宝:D2R Pixel Bot如何解放你的双手

厌倦了在《暗黑破坏神2重制版》中重复刷BOSS、整理背包、管理药水这些枯燥操作吗?D2R Pixel Bot正是为解决这些痛点而生的像素级自动化工具。这款开源工具通过先进的图像识别技术,能够模拟人类操作完成游戏中的重复任务,让玩家专注于构建角色和策略规划,而非机械重复劳动。 ## 核心能力矩阵:D2R Pixel Bot能为你做什么 D2R Pixel Bot不是简单的按键精灵,而是具备智能决

gitblog_01174的博客 814

cocos2dx开发_一款基于Cocos2dx开发的纵版飞行射击单机手游

概述功能介绍本游戏是一款基于Cocos2dx开发的纵版飞行射击单机手游。玩家可以控制一架飞机与敌机进行对战,飞机可以发射子弹、导弹甚至激光,除此之外,玩家还能对自己的飞机进行强化改造,提升基础属性。当玩家完成指定的任务后,还能获取各种类型的道具奖励。游戏操作简单,上手容易,画面逼真炫酷,并有多种道具可供使用。本游戏支持三种游戏模式:闯关模式、无尽模式、急速模式。1. 闯关模式这是一种最常见的玩法,...

weixin_27977279的博客 353

《陈欣与内核的黎明》

它是“源码清除计划”的最终产物,一种可以抹除任意函数、变量、结构体定义的存在。终于,在第 7 天的战斗后,陈欣找到了 Ksplice Null 的核心——一个名为 __no_source__ 的隐藏模块。那是她在很久以前写下的一个内核初始化钩子函数——现在,它成了她对抗 Ksplice Null 的武器。但如今,这一切都被一个名为 Ksplice Null 的实体入侵。它是由一组自修改代码组成的,每次读取它的内容,都会得到不同的结果。一瞬间,她的意识被吸入了一个由页表、调度器和中断向量构成的世界。

2401_83847752的博客 652

mapbox 修改初始位置_⑩的游戏修改小课堂1——WinDepth

咱今天比较闲,所以来误人子弟啦~来讲一讲如何用Cheat Engine与OllyDBG来修改简单的小游戏~当然,这是只最初级的修改(露米娅比较笨qwq),不过,这也意味着非常地简单易学~今天露米娅下载了一个反潜小游戏(WinDepth)来怀旧一下~当年玩到这个游戏的时候,咱还在上幼儿园……系统是win98,ghost系统自带一个十个小游戏的合集,其中就有这个潜艇的小游戏。不过版本可能不同,因为我记...

weixin_39869432的博客 362
上一篇: 声明:目前在网上出现一个跟我同名的人,他的blog是http://blog.youkuaiyun.com/allyesno
下一篇: Internet 协议编号
freexploit
博客等级 码龄22年 315粉丝 778原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值