首页
社区
课程
招聘
12月7日升级――OllyMachine v0.20最终版
发表于: 2004-11-15 20:37 66781

12月7日升级――OllyMachine v0.20最终版

2004-11-15 20:37
66781
收藏
免费 1
支持
分享
最新回复 (244)
雪    币: 2199
活跃值: (1975)
能力值: ( LV12,RANK:810 )
在线值:
发帖
回帖
粉丝
176
最初由 luocong 发布


我刚才特意用OllyScript翻译了一次你的脚本,运行结果:


........


用小键盘的“-”号返回也没有找到原来的代码,我想可能是你设置的恢复原来代码的功能提前了。
2004-11-29 22:40
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
177
最初由 fxyang 发布


用小键盘的“-”号返回也没有找到原来的代码,我想可能是你设置的恢复原来代码的功能提前了。


请问如果是正确的话,应该是停在哪里?能不能贴那段反汇编代码出来?刚刚用OllyScript的脚本试了一下,按小键盘返回的第一个地方跟我的是一样的。附ODS的脚本:

var aOpenMutexA

EOE exception1
gpa "OpenMutexA", "kernel32.dll"
mov aOpenMutexA, $RESULT
bp aOpenMutexA

eob II2I
run

exception1: //异常处理
esto //相当于Shift+F9,应该越过这个异常

II2I:
exec
PUSHAD
PUSH EDX
push 0
push 0
CALL CreateMutexA
POPAD
jmp OpenMutexA
ende
//完成双进程到单进程的转换
bc aOpenMutexA
2004-11-29 22:45
0
雪    币: 2199
活跃值: (1975)
能力值: ( LV12,RANK:810 )
在线值:
发帖
回帖
粉丝
178
我也测试了,在
II2I:
后面加pause能停在OpenMutexA函数中,
现在这个OM运行到OpenMutexA函数中时没有停,好像是在内嵌汇编的入口处挂住了。pause后就停在
77EB6FE5    52              PUSH EDX  //停在这里
77EB6FE6    68 00000000     PUSH 0
77EB6FEB    68 00000000     PUSH 0
77EB6FF0    E8 2346FAFF     CALL kernel32.CreateMutexA
77EB6FF5    61              POPAD
77EB6FF6  ^ E9 ECB2FAFF     JMP kernel32.OpenMutexA

如果用F8运行这个代码就会改变这段代码,出错!
2004-11-29 22:52
0
雪    币: 2199
活跃值: (1975)
能力值: ( LV12,RANK:810 )
在线值:
发帖
回帖
粉丝
179
如果正确的话,这段代码应该运行完,然后停在kernel32.OpenMutexA函数的入口处
2004-11-29 22:53
0
雪    币: 557
活跃值: (2303)
能力值: ( LV9,RANK:2130 )
在线值:
发帖
回帖
粉丝
180
刚看一下就出问题了,请问变量怎么申明呀?直接用reg??,那样表示不好吧,不方便记忆,像osc那样直接var 变量 就方便记很多
2004-11-30 10:09
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
181
最初由 fxyang 发布
如果正确的话,这段代码应该运行完,然后停在kernel32.OpenMutexA函数的入口处


嗯!thanks
2004-11-30 10:11
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
182
最初由 loveboom 发布
刚看一下就出问题了,请问变量怎么申明呀?直接用reg??,那样表示不好吧,不方便记忆,像osc那样直接var 变量 就方便记很多


很遗憾,不支持声明变量,暂时来说只能改变一下习惯了。
2004-11-30 10:14
0
雪    币: 557
活跃值: (2303)
能力值: ( LV9,RANK:2130 )
在线值:
发帖
回帖
粉丝
183
再一个建议,建议把invoke给去掉直接 msg,msgyn等等,少打几个字嘛:D ,那样更方便我从osc上转过来.变量可以自己定义一个名字就最好了
2004-11-30 10:16
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
184
最初由 loveboom 发布
再一个建议,建议把invoke给去掉直接 msg,msgyn等等,少打几个字嘛:D ,那样更方便我从osc上转过来.变量可以自己定义一个名字就最好了


很遗憾,这两点都无法实现。

其实都是习惯问题了。在TASM里面连invoke宏都没有呢,所有的API都要先一个一个参数进行push,最后才来一个call,大家也还是能接受的。

至于变量的命名,我只能抱歉地说一句:目前我没有时间去做。OllyScript能做到这一点,是因为它用了CArray,不分青红皂白就把所有的变量保存在一个数组里了,不区分类型,由于没有任何语义检查,所以起变量名这个功能它实现起来比较简单,但代价是:
1、不严谨。这是我最无法容忍的。例如对一个字符串进行inc操作居然是允许的。
2、浪费内存,速度慢。
3、维护有一定的困难。

但我必须承认,从使用者的角度来看,越傻瓜化越好,然而作为一个开发者,我还是希望我的源代码是严谨而高效并且易于维护的。如果我要实现起变量名这个功能,我是肯定要去做语义检查的,但我目前没那么多时间。

将来等我没心思再去维护它的时候,按照惯例我会开源的。
2004-11-30 10:26
0
雪    币: 2199
活跃值: (1975)
能力值: ( LV12,RANK:810 )
在线值:
发帖
回帖
粉丝
185
仔细的跟踪了内嵌汇编的过程,似乎在写入汇编代码的循环中没有出来。就是停在kernel32.OpenMutexA入口处停下的原因。
pause后F8会进入下面的代码:
03BD8720    53              PUSH EBX
03BD8721    56              PUSH ESI
03BD8722    8BF1            MOV ESI,ECX
03BD8724    57              PUSH EDI
03BD8725    8B7C24 10       MOV EDI,DWORD PTR SS:[ESP+10]
03BD8729    33DB            XOR EBX,EBX
03BD872B    8B86 A0040000   MOV EAX,DWORD PTR DS:[ESI+4A0]
03BD8731    8D0C07          LEA ECX,DWORD PTR DS:[EDI+EAX]
03BD8734    8A4407 01       MOV AL,BYTE PTR DS:[EDI+EAX+1]
03BD8738    8886 E40C0000   MOV BYTE PTR DS:[ESI+CE4],AL
03BD873E    25 FF000000     AND EAX,0FF
03BD8743    2BC3            SUB EAX,EBX
03BD8745    74 2B           JE SHORT OllyMach.03BD8772
03BD8747    48              DEC EAX
03BD8748    75 5D           JNZ SHORT OllyMach.03BD87A7
03BD874A    8BCE            MOV ECX,ESI
03BD874C    E8 EF000000     CALL OllyMach.03BD8840
03BD8751    85C0            TEST EAX,EAX
03BD8753    74 52           JE SHORT OllyMach.03BD87A7
03BD8755    8B8E A0040000   MOV ECX,DWORD PTR DS:[ESI+4A0]
03BD875B    8B86 E00C0000   MOV EAX,DWORD PTR DS:[ESI+CE0]
03BD8761    85C0            TEST EAX,EAX
03BD8763    8B540F 02       MOV EDX,DWORD PTR DS:[EDI+ECX+2]
03BD8767    8B8C96 EF0C0000 MOV ECX,DWORD PTR DS:[ESI+EDX*4+CEF]
03BD876E    74 37           JE SHORT OllyMach.03BD87A7
03BD8770    EB 0D           JMP SHORT OllyMach.03BD877F
03BD8772    8B86 E00C0000   MOV EAX,DWORD PTR DS:[ESI+CE0]
03BD8778    8B49 02         MOV ECX,DWORD PTR DS:[ECX+2]
03BD877B    85C0            TEST EAX,EAX
03BD877D    74 28           JE SHORT OllyMach.03BD87A7
03BD877F    8B96 EA0C0000   MOV EDX,DWORD PTR DS:[ESI+CEA]
03BD8785    48              DEC EAX
03BD8786    83C2 FC         ADD EDX,-4
03BD8789    8986 E00C0000   MOV DWORD PTR DS:[ESI+CE0],EAX
03BD878F    8996 EA0C0000   MOV DWORD PTR DS:[ESI+CEA],EDX
03BD8795    898C86 E0040000 MOV DWORD PTR DS:[ESI+EAX*4+4E0],ECX  //这里好像写入了什么
03BD879C    5F              POP EDI
03BD879D    5E              POP ESI
03BD879E    B8 01000000     MOV EAX,1
03BD87A3    5B              POP EBX
03BD87A4    C2 0400         RETN 4

然后进入这个循环:
03BDC11A    8B96 A0040000   MOV EDX,DWORD PTR DS:[ESI+4A0]
03BDC120    8B86 E60C0000   MOV EAX,DWORD PTR DS:[ESI+CE6]
03BDC126    B9 04000000     MOV ECX,4
03BDC12B    8A0402          MOV AL,BYTE PTR DS:[EDX+EAX]
03BDC12E    8886 E50C0000   MOV BYTE PTR DS:[ESI+CE5],AL
03BDC134    25 FF000000     AND EAX,0FF
03BDC139    83F8 6D         CMP EAX,6D
03BDC13C    0F87 FF130000   JA OllyMach.03BDD541
03BDC142    FF2485 A8D6BD03 JMP DWORD PTR DS:[EAX*4+3BDD6A8]
03BDC149    FF86 E60C0000   INC DWORD PTR DS:[ESI+CE6]
03BDC14F    E9 F3130000     JMP OllyMach.03BDD547
03BDC154    8B8E E60C0000   MOV ECX,DWORD PTR DS:[ESI+CE6]
03BDC15A    6A 02           PUSH 2
03BDC15C    51              PUSH ECX
03BDC15D    8BCE            MOV ECX,ESI
03BDC15F    E8 ACCBFFFF     CALL OllyMach.03BD8D10
03BDC164    3BC7            CMP EAX,EDI
03BDC166    75 06           JNZ SHORT OllyMach.03BDC16E
…………
03BDD552    3BC5            CMP EAX,EBP
03BDD554    75 26           JNZ SHORT OllyMach.03BDD57C
03BDD556    8B86 E60C0000   MOV EAX,DWORD PTR DS:[ESI+CE6]
03BDD55C    3BC7            CMP EAX,EDI
03BDD55E    7C 12           JL SHORT OllyMach.03BDD572
03BDD560    3B86 A4040000   CMP EAX,DWORD PTR DS:[ESI+4A4]
03BDD566    7F 0A           JG SHORT OllyMach.03BDD572
03BDD568    8BC5            MOV EAX,EBP
03BDD56A    8986 C0040000   MOV DWORD PTR DS:[ESI+4C0],EAX
03BDD570    EB 0E           JMP SHORT OllyMach.03BDD580
03BDD572    33C0            XOR EAX,EAX
03BDD574    8986 C0040000   MOV DWORD PTR DS:[ESI+4C0],EAX
03BDD57A    EB 04           JMP SHORT OllyMach.03BDD580
03BDD57C    3BC7            CMP EAX,EDI
03BDD57E    74 0C           JE SHORT OllyMach.03BDD58C
03BDD580    39AE C0040000   CMP DWORD PTR DS:[ESI+4C0],EBP
03BDD586  ^ 0F84 8EEBFFFF   JE OllyMach.03BDC11A  //循环开始

老罗参考看看,是不是运行内嵌代码的处理过程有问题。
2004-11-30 11:12
0
雪    币: 383
活跃值: (786)
能力值: ( LV12,RANK:730 )
在线值:
发帖
回帖
粉丝
186
给OllyMachine提点改良的建议

1.
改变 API 进行操作时返回的错误或失败是为-1的值,为何不能改为返回0,或者你只需要将-1求反就能变为0

cmp reg00,-1
cmp reg00,0xffffffff

cmp reg00,0
cmp reg00,0x0

// 由此可看出,用 0 作为失败,比用 -1 作为失败要简化,我相信变成汇编机器码表示 0 要比表示-1要来得省和好,不知对不对?

2.
ReplaceBytes address, find, repl, len
// 这条 API 似乎功能不够灵活实用,len 能否改为这样定义:len是从 address 开始搜索替换的范围(长度),比如:

invoke replacebytes,401000,0xcc,0x90,1000
// 表示从401000到402000的范围内,替换所有cc为90,402000 就是等于 address+len
// 另外,返回值可送到 reg00,表示替换的数量,0 表示没有成功,非 0 表示成功数量,似乎“返回找到的地址”意义不大(因为 find)

3.
// nop API作用没什么必要吧,就删除它行吧?我不知道它对你修bug有什么作用...

4.
find 和 search API 如果没有区别,没必要开多其中一个

5.
__asm
{
pushfd
pushad
push 0
call GetModuleHandleA
cmp eax,0
je lbl1
push // 1.6版本的(1.7没到手),居然编译成功这里为何不出语法错误
popad
popfd
jmp end

lbl1:
popad
popfd
push 0
call ExitProcess

end:
nop
}
invoke msg,"Great,run perfect!"

//内嵌不知是否支持标签,运行结果没有达到目的,eax最终为程序模块值。
2004-11-30 11:24
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
187
真诚感谢fxyang!我先收藏你的研究结果,回头对比一下代码。
2004-11-30 11:42
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
188
感谢askformore提供那么多的改良建议!我来解释一下:

1.
改变 API 进行操作时返回的错误或失败是为-1的值,为何不能改为返回0,或者你只需要将-1求反就能变为0


有些API的返回值如果用0来表示错误的话,是不够严谨的。我举个例子:

invoke ReadMemLong, eip, 4


有可能读到的数据本身就是0,这时如果用0来表示错误的话,那么就是一个bug了。但诚如你所说的,用0是最方便的,不过既然现在已经用-1了,那就不改了,否则以前别人写过的一些脚本可能就出错了。

2.
ReplaceBytes address, find, repl, len
// 这条 API 似乎功能不够灵活实用,len 能否改为这样定义:len是从 address 开始搜索替换的范围(长度),比如:

invoke replacebytes,401000,0xcc,0x90,1000
// 表示从401000到402000的范围内,替换所有cc为90,402000 就是等于 address+len
// 另外,返回值可送到 reg00,表示替换的数量,0 表示没有成功,非 0 表示成功数量,似乎“返回找到的地址”意义不大(因为 find)


这个建议非常好,我会新增一个API来实现这个功能。

3.
// nop API作用没什么必要吧,就删除它行吧?我不知道它对你修bug有什么作用...


对一般的应用来说的确是没用的,但它有个特殊的用处,是用在虚拟机内部的:我在OllyMachine的指令集里面,把NOP指令的opcode设置为0,这意味着如果虚拟机遇到了特殊的情况(比如异常)导致跑“飞”了,而跑飞的地方的数据是0(这是很有可能的),那么虚拟机会认为这个地方是NOP,从而可以继续运行下去,只不过是多浪费一个指令周期而已。

4.
find 和 search API 如果没有区别,没必要开多其中一个


Find和Search还是有区别的,区别在于:

Search与Find的不同之处在于,Search并不会从一个合法的Opcode的起始地址开始搜寻。
例如:

004010DC 55 PUSH EBP
004010DD 8BEC MOV EBP,ESP
004010DF 6A FF PUSH -1


如果用invoke Find, eip, "EC6AFF",那么不会找到,返回-1;
如果用invoke Search, eip, "EC6AFF",那么会返回004010DE。

5.
__asm
{
pushfd
pushad
push 0
call GetModuleHandleA
cmp eax,0
je lbl1
push // 1.6版本的(1.7没到手),居然编译成功这里为何不出语法错误
popad
popfd
jmp end

lbl1:
popad
popfd
push 0
call ExitProcess

end:
nop
}
invoke msg,"Great,run perfect!"

//内嵌不知是否支持标签,运行结果没有达到目的,eax最终为程序模块值。


1、在0.17版里面,我重写了内嵌汇编的词法和语法分析器,上面所提到的push这条指令没有被检测出来,的确在0.16里面存在,但在0.17里面已经不会出现了。
2、内嵌不支持标签。我会在将来的版本中继续改进内嵌汇编的功能。

最后补充一句:有的时候也许会觉得OllyMachine的一些设计上存在很不可思议的地方,这很可能是历史遗留问题导致的,例如刚刚开始没有考虑到某种情况,然后在使用者的反馈下我决定新增某个功能...
2004-11-30 11:55
0
雪    币: 117
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
189
支持,我来晚了。
2004-11-30 12:48
0
雪    币: 3814
活跃值: (4382)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
190
喝多了,再来顶一下小罗。:o
2004-11-30 13:46
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
191
to fxyang:
我后来重新跟踪了一次OllyMachine的源代码,发现并不是OM的bug。我修改了一下你的脚本,如下,可以正确运行了:

EOE OnException1

invoke GetProcAddress, "OpenMutexA","kernel32.dll"
mov reg01,reg00
invoke bp reg01
eob II2I
mov reg10, -1 // 设置一个标志位,用来表示是否已经运行过嵌入汇编了
run

OnException1: // 异常处理
esto // 相当于Shift+F9,应该越过这个异常

II2I:

// 完成双进程到单进程的转换
invoke bc reg01

cmp reg10, -1 // 是否已经运行过嵌入汇编了?
jne II2I_End // 没有运行过,这是第一次

mov reg10, 0 // 标志位设置为非-1即可,以后就不会再运行了

__asm
{
PUSHAD
PUSH EDX
push 0
push 0
CALL CreateMutexA
POPAD
jmp OpenMutexA
}

II2I_End:
invoke msg, "现在我们位于OpenMutexA函数体的第一条指令了!"


其实关键的地方在于脚本的逻辑有问题。应该判断一下是否已经到达过OpenMutexA的函数体了,否则就会陷入一个死循环中。

不知道我对你的脚本的逻辑的理解是否正确?请指教。
2004-11-30 19:49
0
雪    币: 2199
活跃值: (1975)
能力值: ( LV12,RANK:810 )
在线值:
发帖
回帖
粉丝
192
OK,修改的OM能运行了,只是我不能理解为什么要判断是不是运行过内嵌汇编?运行一次就应该到下面的语句了,是什么造成循环的呢?脚本中没有这个循环呀?
2004-11-30 20:29
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
193
最初由 fxyang 发布
OK,修改的OM能运行了,只是我不能理解为什么要判断是不是运行过内嵌汇编?运行一次就应该到下面的语句了,是什么造成循环的呢?脚本中没有这个循环呀?


这个跟OllyMachine虚拟机的内部实现有关,现在我正在写0.18的文档,等一会再说……
2004-11-30 20:35
0
雪    币: 2199
活跃值: (1975)
能力值: ( LV12,RANK:810 )
在线值:
发帖
回帖
粉丝
194
期待你的完美:p
2004-11-30 20:48
0
雪    币: 82
活跃值: (321)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
195
正看着要下
突然变出0.18版了
升级好快:p
2004-11-30 22:05
0
雪    币: 1583
活跃值: (831)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
196
OllyMachine 0.18版发布。

地址: http://www.luocong.com/om

更新如下:

1. 新增:两个新的搜索API:
* ReverseFind
* ReverseSearch

2. 新增:两个新的替换API:
* CopyBytesTo
* ReplaceBytesEx

3. 修正:在Search中的一个bug,有时会导致无法找到正确的地址。

说明:

1、ReverseFind和ReverseSearch的功能跟Find和Search一样,唯一的区别在于它们是往前进行搜索的。

2、CopyBytesTo的示例:

invoke CopyBytesTo, eip, 0x401000, 10


它的作用是把eip处的10个字节拷贝到0x401000处。

3、ReplaceBytesEx的示例:

invoke ReplaceBytesEx, eip, 10, "60e8??", "909090"


它的作用是,从eip开始,在10个字节范围内,把"60e8??"替换成"9090??"。注意事项:

1、准备替换的字节数和替换成的字节数必须相同。例如假如源码为"60e8??",表示3个字,那么替换成的字节码也必须是3个字节。
2、在源码里面的"??"不会被替换。例如假如源码为"60e8??",替换成的字节码为"123456",
   那么替换后将会是"1234??",原来的"??"所表示的那个字节不变。
2004-11-30 22:08
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
197
:D thx
2004-11-30 22:12
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
198
升级得好快。。。。等稍微稳定了,再下载来好好学;)
2004-11-30 22:29
0
雪    币: 98674
活跃值: (200999)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
199
最初由 luocong 发布
OllyMachine 0.18版发布。

地址: http://www.luocong.com/om

更新如下:
........


辛苦!!!
支持!!!
2004-11-30 22:31
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
200
最初由 玉川 发布
升级得好快。。。。等稍微稳定了,再下载来好好学;)

越测试,越稳定
2004-11-30 22:50
0
游客
登录 | 注册 方可回帖
返回
//