列表word['a','b','c','d','e','f','g']
b=word[1:3]
print(b)
这里输出的是b,c。
总结:1、3指的是下标为1和3的元素,输出下标为1和下标为3之间的元素(包括“:”之前的元素而不包括“:”之后的元素)
posted @
2013-04-26 15:13 寻步 阅读(314) |
评论 (0) |
编辑 收藏
[病毒在线扫描]
http://www.virustotal.com
http://www.filterbit.com
http://www.virscan.org
http://virusscan.jotti.org
http://online.us.drweb.com
[沙盘在线分析]
http://anubis.iseclab.org
http://eureka.cyber-ta.org
http://www.threatexpert.com
http://camas.comodo.com/cgi-bin/submit
http://www.joebox.org/submit.php
http://mwanalysis.org/?site=1&page=submit
http://www.suspectfile.com/index.php
https://analysis.f-secure.com/portal/login.html
https://aerie.cs.berkeley.edu/submitsample-d.php
http://autovin.pandasecurity.my/?page_id=332
[WEB 安全工具]
http://linkscanner.explabs.com/linkscanner/default.aspx
http://vurl.mysteryfcm.co.uk/
http://malfease.oarci.net/
http://sandsprite.com/shellcode_2_exe.php
http://jsunpack.jeek.org/dec/go
http://web-sniffer.net
http://wepawet.iseclab.org
http://www.yougetsignal.com/tools/visual-tracert/
http://www.cproxyer.com
http://tools88.com/
http://www.exploit-db.com/
http://www.ip866.com
http://www.mxcz.net/tools/
http://just-ping.com/
http://www.yougetsignal.com/
还有 扬中河豚素1号。
posted @
2013-03-14 12:00 寻步 阅读(998) |
评论 (1) |
编辑 收藏
一.脱壳基础知识要点
1.PUSHAD :(压栈) 代表程序的入口点
2.POPAD :(出栈) 代表程序的出口点,与PUSHAD想对应.看到这个,就说明快到OEP了.
3.OEP:程序的入口点,软件加壳就是隐藏OEP.而我们脱壳就是为了找OEP.
二.脱壳调试过程中辨认快到OEP的简单方法
下面二个条件是快到OEP的共同现象:
若出现下面情况时,说明OEP就要到了:
1. OD跟踪过程中如果发现:
popad
popfd
或
popad
2.同时,紧接着,有retn ,jmp等其它跳转指令,发生跨段跳跃时.
说明OEP马上到了.
三.脱壳必需牢记的要领
1.单步往前走,不要让程序向上走,遇到向上跳时,在下一句按F4,运行到所选.
2.刚载入程序,在附近就call时,我们按F7跟进去.
3.若跟踪时,运行某个call程序就运行时,这个call也用F7进入.
4.在跟踪时,出现比如 jmp XXXXXX 或者 JE XXXXXX 或者有RETN同时发生大跨段跳转时,说明很快就到OEP了.
四.常用脱壳方法总结
------------------
方法一:单步跟踪法
------------------
介绍:这是最通用的方法,对于未知壳,基本都用这种方法,这种方法过程比较麻烦,要一步一步的跟踪分析,要有一定的耐心.
1.用OD载入,选"不分析代码"
2.单步向下跟踪按F8,实现向下的跳.不让程序往回跳.
3.遇到程序往回跳的(包括循环),我们在下一句代码处按F4(或者右健单击代码,选择断点——>运行到所选)
4.如果刚载入程序,在附近就有一个CALL的,我们就F7跟进去,不然程序很容易运行.
5.在跟踪的时候,如果运行到某个CALL程序就运行的,就在这个CALL中F7进入.
6.一般遇到很大的跳转(跨段跳),比如 jmp XXXXXX 或 JE XXXXXX 或有RETN的一般很快就会到程序的OEP。
-----------------
方法二:ESP定律法
-----------------
介绍: 这种方法可以脱大部的压缩壳和少数加密壳,操作起来比较简单,脱壳速度也相对比较快.
1.开始就点F8向下走,注意观察OD右上角的寄存器中ESP有没突现(变成红色)
2.在命令行下:dd XXXXXXXX(指在当前代码中的ESP地址,或者hr
XXXXXXXX),按回车!
3.选中下断的地址,断点--->硬件访问--->WORD断点。
4.按一下F9运行程序,直接来到了跳转处,按下F8向下走,就到达程序OEP。
-----------------
方法三:内存镜像法
-----------------
介绍:也是一种比较好用的脱壳方法,大部分的压缩壳和加密壳用内存镜像法能快速脱掉.非常实用.
1.用OD打开,设置选项——调试选项——异常,忽略所有异常(也就是把里面的忽略全部√上),然后CTRL+F2重载下程序!
2.按ALT+M,打开内存镜象,找到程序的第一个.rsrc.按F2下断点,然后按SHIFT+F9运行到断点.
3.接着再按ALT+M,打开内存镜象,找到程序的第一个.rsrc.上面的.CODE,按F2下断点!然后按SHIFT+F9,直接到达程序OEP!
----------------
方法四:一步到OEP
----------------
介绍:这是一种巧方法,脱壳速度最快,前提是要知道这个壳的特征,利用这种壳的共性快速找到程序的OEP.这种方法只用于少数壳.
1.开始按Ctrl+F,输入:popad,然后按下F2下断,按F9运行到此处.
2.很快来到大跳转,按F8向下走,来到OEP.
----------------------
方法五:最后一次异常法:
----------------------
介绍:这种方法一般用于加密壳,这是脱加密壳的一种通用方法.
第一步:用OD打开程序,点击选项——调试选项——异常,把里面的√全部去掉!CTRL+F2重载下程序.
第二步:接着我们按SHIFT+F9,直到程序运行,记下从开始按SHIFT+F9到程序运行的次数n.
第三步:重载程序,再按SHIFT+F9,这次按的次数为上次让程序运行时的次数的n-1次.
第四步:此时观察OD的右下角有一个"SE 句柄",这时我们按CTRL+G,输入SE 句柄前的地址!来到这个地址.
第五步:在这里,按F2下断点!然后按SHIFT+F9来到断点处!
第六步:这时候我们已经跳过了所有异常,然后去掉断点,按F8慢慢向下跟踪很快就到达OEP了.
posted @
2013-03-13 16:05 寻步 阅读(1298) |
评论 (0) |
编辑 收藏
标 题: 【原创】OD被Anti的原因分析及应对之道
作 者: tangjiutao
时 间: 2009-12-02,22:21:56
链 接: http://bbs.pediy.com/showthread.php?t=102366
本文链接:http://bbs.pediy.com/showthread.php?t=102366
OD载入程序就自动退出是比较恼人的,还没开始调试呢就退出了,这可让人如何是好。初学破解的人一定会遇到这个问题,怎样解决呢,网上虽然有零星的介绍但都不全面,以下是我总结的一些,希望能对各位初学者有所帮助。
(比如Peid、FI查壳查不到,OD一载入就退出,这极有可能是VMProtect的保护(虚拟机保护),用EXEinfo可以查出来一些版本的VMP,如果有这个提示那就更确定无疑了“A debugger has been found running in your system.Please, unload it from memory and restart your program”。)
1.更换几个OD试试,OllyICE、Shadow、加强版等2.用附加的方式加载程序,文件-->附加,能解决很多问题3.OD目录下,将475K 的DbgHelp.dll文件换成近1M大小的DbgHelp.dll文件,475K的有溢出漏洞,这条比较关键4.使用StrongOD插件,(StrongOD+原版OD试试),这条比较关键5.StrongOD中选择CreateAsRestrict
6.尝试命令bp ExitProcess,看能否发现什么线索
7.改变ollydbg.ini中的驱动名称,修改版的OD不需要自己改
DriverName - 驱动文件名,设备对象名
DriverKey - 和驱动通信的key
HideWindow - 是否隐藏窗口,1为隐藏,0为不隐藏
HideProcess - 是否隐藏od进程,1为隐藏,0为不隐藏
ProtectProcess - 是否隐藏保护Od进程,1为保护,0为不保护
8.改OD窗体类名,用的修改版的话一般都改过了,不需要自己再改
方法如下:
主窗体类名:
引用:
VA:004B7218
Offset:000B6018
各子窗体类名:
引用:
VA:004B565B ~ 004B568A
Offset:000B445B ~ 000B448A
改成任意,可以过GetWindow检测
9.手动修改程序“导出表”中的“函数名数目”值,上面方法不管用再试试它
方法:使用“LordPE”打开要编辑的PE程序,然后依次选择[目录]->[导出表对应的“..”按钮],把“函数名数目”的值减1,并点击“保存”按钮,就OK了。为了好看些,也可以把“函数数目”和“函数名数目”的值都同时减1并保存,效果一样。
解释:一般情况下EXE不会加“导出表”,如果加了,就应该给出所导出的API函数。当我们打开这类PE程序(EXE版)时,会发现它存在“导出表”,但“导出表”中并没有导出的API函数。同时“函数数目”和“函数名数目”的值都比原PE程序设置的值大了1(如:EXE版“导出表”列表中显示了0个导出的API函数,壳将其“函数数目”和“函数名数目”的值都设置成了1;DLL版“导出表”列表中显示了0xD个导出的API函数,壳将其“函数数目”和“函数名数目”的值都设置成了0xE。)。所以我们将其减1,就OK了。被修改过的PE程序,可以正常运行,不会有任何影响。
这只是我的一点总结,附加方式加载、替换DBGHELP.DLL、使用StrongOD插件和修改导出表函数名数目的方法是可行的,能够解决一些问题。当然这些方法可能并不全面。
ANTI-OD原因解读: 概括来说:TLS回调函数在入口点之前执行,并进行了ANTI-OD的操作.
具体请看:TLS数据初始化和TLS回调函数都会在入口点之前执行,也就是说TLS是程序最开始运行的地方,因此可以在这里防止ANTI-OD的代码,检测并关闭OD。
应对方法:
默认情况下OllyDbg载入程序将会暂停在入口点,应该配置一下OllyDbg使其在TLS回调被调用之前中断在实际的loader。
通过“选项->调试选项->事件->第一次中断于->系统断点”来设置中断于ntdll.dll内的实际loader代码。这样设置以后,OllyDbg将会中断在位于执行TLS回调的ntdll!LdrpRunInitializeRoutines()之前的ntdll!_LdrpInitializeProcess(),这时就可以在回调例程中下断并跟踪了。例如:在内存映像的.text代码段上设置内存访问断点,就可以断在TLS回调函数里。
更多TLS内容请看我的两篇博文:
TLS回调函数,Anti-od原理分析:
http://hi.baidu.com/tjt999/blog/item...808f7eff1.htmlTLS回调函数,Anti-od实例:
http://hi.baidu.com/tjt999/blog/item...f359bf7f3.html更多反调试知识请看《脱壳的艺术》和我的
《各种反调试技术原理与实例》:
http://bbs.pediy.com/showthread.php?t=106143如需交流请进群:1684360
实例代码:程序见附件,用原版OD测试,参考了某位大虾的代码。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data?
dwTLS_Index dd ?
OPTION DOTNAME
;; 定义一个TLS节
.
tls SEGMENT
TLS_Start LABEL DWORD
dd 0100h dup ("slt.")
TLS_End LABEL DWORD
.
tls ENDS
OPTION NODOTNAME
.data
TLS_CallBackStart dd TlsCallBack0
TLS_CallBackEnd dd 0
szTitle db "Hello TLS",0
szInTls db "我在TLS里",0
szInNormal db "我在正常代码内",0
szClassName db "ollydbg" ; OD 类名
;这里需要注意的是,必须要将此结构声明为PUBLIC,用于让连接器连接到指定的位置,
;其次结构名必须为_
tls_uesd这是微软的一个规定。编译器引入的位置名称也如此。
PUBLIC _
tls_used
_
tls_used IMAGE_TLS_DIRECTORY <TLS_Start, TLS_End, dwTLS_Index, TLS_CallBackStart, 0, ?>
.code
;***************************************************************
;; TLS的回调函数
TlsCallBack0 proc Dllhandle:LPVOID,dwReason:DWORD,lpvReserved:LPVOID
mov eax,dwReason ;判断dwReason发生的条件
cmp eax,DLL_PROCESS_ATTACH ; 在进行加载时被调用
jnz ExitTlsCallBack0
invoke FindWindow,addr szClassName,NULL ;通过类名进行检测
.if eax ;找到
invoke SendMessage,eax,WM_CLOSE,NULL,NULL
.endif
invoke MessageBox,NULL,addr szInTls,addr szTitle,MB_OK
mov dword ptr[TLS_Start],0
xor eax,eax
inc eax
ExitTlsCallBack0:
ret
TlsCallBack0 ENDP
;****************************************************************
Start:
invoke MessageBox,NULL,addr szInNormal,addr szTitle,MB_OK
invoke ExitProcess, 1
end Start
参考文献:
http://www.unpack.cn/viewthread.php?tid=35013&extra=page%3D1
posted @
2013-01-07 10:10 寻步 阅读(1059) |
评论 (0) |
编辑 收藏
摘要: 摘自:http://www.cnblogs.com/huhu0013/archive/2011/07/05/2098358.html一、 前言 前段学习反调试和vc,写了antidebug-tester,经常会收到message希望交流或索要实现代码,我都没有回复。其实代码已经在编程版提供了1个版本,另其多是vc内嵌asm写的,对cracker而言,只要反下就知...
阅读全文
posted @
2013-01-05 10:59 寻步 阅读(2435) |
评论 (0) |
编辑 收藏
- Windows核心编程书(思想)
- C++、汇编(语言)
- OD、IDA验证思想(工具)
posted @
2012-12-29 15:07 寻步 阅读(554) |
评论 (0) |
编辑 收藏
int main(int argc, char* argv[])
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
HMODULE hMod = GetModuleHandle(NULL);
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;
IMAGE_OPTIONAL_HEADER* pOptHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hMod+pDosHeader->e_lfanew+24);
IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hMod+pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (pImportDesc->FirstThunk)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
char* pszDllName = (char*)((BYTE*)hMod+pImportDesc->Name);
printf("\nModule Name:%s\n",pszDllName);
![](/Images/OutliningIndicators/InBlock.gif)
IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hMod+pImportDesc->OriginalFirstThunk);
int n = 0;
while (pThunk->u1.Function)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
char* pszFunName = (char*)((BYTE*)hMod+(DWORD)pThunk->u1.AddressOfData+2);
PDWORD lpAddr = (DWORD*)((BYTE*)hMod+pImportDesc->FirstThunk)+n;
printf("Fuction Name:%-27s,",pszFunName);
printf("Fuction Address:%X\n",*lpAddr);
n++;
pThunk++;
}
pImportDesc++;
}
![](/Images/OutliningIndicators/InBlock.gif)
getchar();
![](/Images/OutliningIndicators/InBlock.gif)
return 0;
}得到输入表地址:
![](/images/cppblog_com/xunbu7/QQ截图20121228170123.jpg)
后面的两个循环:
posted @
2012-12-28 17:01 寻步 阅读(476) |
评论 (0) |
编辑 收藏
SYSTEM_INFORMATION_CLASS是一个类型信息,它大概提供了50余种信息,所以你需要哪一种信息,就需要设置一个枚举值。
enum SYSTEM_INFORMATION_CLASS {SystemKernelDebuggerInformation=35};
这样得到的是SYSTEM_KERNEL_DEBUGGER_INFORMATION这个结构体代表的信息。
SYSTEM_INFORMATION_CLASS的完整定义:
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
} SYSTEM_INFORMATION_CLASS;
posted @
2012-12-27 14:34 寻步 阅读(1895) |
评论 (0) |
编辑 收藏
感谢两文作者!
http://techird.blog.163.com/blog/static/1215640362011112385241568/http://www.cnblogs.com/BoyXiao/archive/2011/07/31/2122755.html 所有的配置工作完成后,在新的调试的时候,需要注意的是:
每次在重启虚拟机的时候,在选择操作系统的界面要停一下,等待我们机器上的VS上相关的操作。
![](/images/cppblog_com/xunbu7/QQ截图20121226173704.jpg)
1.驱动文件编译连接后,下好调试断点(这些东西之前就要做好),
2.调试运行驱动。
![](/images/cppblog_com/xunbu7/QQ截图20121226174849.jpg)
3.出现下面的连接虚拟机的连接内核调试对话窗口。
![](/images/cppblog_com/xunbu7/QQ截图20121227094509.jpg)
此时显示的失败。
4.进入虚拟机调试系统,会中断在下面的界面。
![](/images/cppblog_com/xunbu7/QQ截图20121226180231.jpg)
连接虚拟机的连接内核调试对话窗口显示数据信息,代表连接虚拟机成功,窗口很快就消失了,不好截图。
紧接着下载符号窗口,这个图不好截,借用别人一下。
![](/images/cppblog_com/xunbu7/2866822637815190354.jpg)
VS会出现如下控制台界面:
![](http://www.cppblog.com/images/cppblog_com/xunbu7/QQ截图20121227093727.jpg)
5.在VS中按F5运行,则虚拟机系统正常运行。
![](/images/cppblog_com/xunbu7/QQ截图20121226180938.jpg)
6.在虚拟机进入桌面后,DDKLauncherMonitor启动后,等待我们在ddk控制台加载驱动。
![](/images/cppblog_com/xunbu7/QQ截图20121226181818.jpg)
7.控制台加载驱动后,会显示几行错误信息,这个是正常的。
![](/images/cppblog_com/xunbu7/QQ截图20121227100313.jpg)
此时,虚拟机中的DDKLaunchMonitor对话框会显示两行信息。
![](/images/cppblog_com/xunbu7/QQ截图20121227100141.jpg)
结果在VS中断到了我们的断点上,可以成功调试。
![](/images/cppblog_com/xunbu7/QQ截图20121227100832.jpg)
8.一次完成调试后(调试中,虚拟机中的操作系统是不能动的,因为它在被调试,废话,哈哈),虚拟机中的DDKLaunchMonitor对话框会显示一行信息。虚拟机中的操作系统正常运行。
![](/images/cppblog_com/xunbu7/QQ截图20121227102139.jpg)
9.在不关闭虚拟机的前提下,可以反复轻松调试。
posted @
2012-12-26 16:17 寻步 阅读(1193) |
评论 (0) |
编辑 收藏
游戏里“人物”是以对象形式存在。
对象有很多“属性”,和“方法”,
“人物“可以有血,蓝,坐标x,坐标y。等等属性。
可以有“攻击”,“选怪”,“走路”等方法。
在游戏编程的时候,定义了一个对象。
他的属性是按照线性的地址排列。
“对象”在内存中的地址,就是基址。
“属性”和“方法”相对于对象的内存排列,就是偏移。
比如刚开始,游戏定义了“人物”对象具有,1.血2.蓝3.坐标x.4.坐标y
这时候,血值相当于“对象”基址的偏移就是4,蓝的偏移就是8,坐标x就是12,坐标y就是16
然后大更新了一次,游戏给“人物”对象添加了一个属性“经验”。且插入在在"2.蓝"这个属性之后,这时候,其他属性的“相对于对象基址的偏移”就发生了改变。
1.血2.蓝3.经验4.坐标x.5.坐标y
血偏移4,蓝8,经验12,坐标x16,坐标y20。。依次类推。
游戏一般会维护一个“对象列表”,就是把“对象“在内存中的地址存放在特定的数据结构之中,这个数据结构可以是”数组“,”链表“,”树“之类的。
posted @
2012-12-26 10:09 寻步 阅读(1247) |
评论 (0) |
编辑 收藏