- 注册时间
- 2004-11-27
- 最后登录
- 1970-1-1
|
由于我没有星星了,导致我所有的东西在电脑上完成,但是电脑上的虚拟机和星星上的又不一样,所以没有能得到最终结果,但本人认为可行。
原理:
函数在执行前会先将5个字节的数据进栈,它们是将被执行的函数使用的内存的基址和返回地址,是可以修改的。
思路:
因为可以劫持函数的返回地址,又在电脑上的虚拟机上发现可以追加被载入的LAVA文件(其他方式试过了不行),所以由此写了个程序测试。
不过在电脑上的运行结果是虚拟机崩溃,****不能为read,分析原因可能是因为虚拟机在载入文件前分配了与LAVA文件大小相同的内存,而我把程序劫持到了超出此大小的地址,虚拟机访问了不该访问的内存,故挂掉了,LEE大概也没想到会发生这种事吧。而星星上的虚拟机在使用LAVA文件时好像并不是打开,而是直接读的闪存,故应该可以在“运行”时读写自身。
星星还在的帮个忙运行一下,看看结果是不是打印“hello, world!”:P- /*
- 例程(确定无误):
- void main()
- {
- printf("abc");
- hijackTo(16);
- }
- 效果是不停打印出"abc"。
- */
- /*
- 以下待查:
- invoke printf, 1, "hello, world!"
- push 0
- ret
- */
- char code[] = {0x0D, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20,
- 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x01,
- 0x01, 0x82, 0x01, 0x00, 0x3f};
- //取得此函数执行后要返回的地址
- /*
- long getIPtr()
- {
- long IPtr;
- *(&IPtr) = *(&IPtr -5);
- *(&IPtr + 1) = *(&IPtr - 4);
- *(&IPtr + 2) = *(&IPtr - 3);
- *(&IPtr + 3) = 0;
- return IPtr;
- }
- */
- //修改函数执行后要返回的地址
- //相当于运行时的goto
- void hijackTo(long newIPtr)
- {
- *(&newIPtr - 5) = *(&newIPtr);
- *(&newIPtr - 4) = *(&newIPtr + 1);
- *(&newIPtr - 3) = *(&newIPtr + 2);
- }
- //自定义byte code的返回值要放在栈顶,会由exec子程式返回
- //因为种种原因,打开方式是APPEND
- //随着使用次数增加,文件本身大小会变大
- long execMyBytes(long bytes, long size)
- {
- char fp;
- long newIPtr;
- if(!size)
- return -1;
- //此文件名称
- if((fp=fopen("test.lav", "ab+")) == 0)
- {
- printf("file open err\n");
- return -1;
- }
- newIPtr = ftell(fp);
- if(fwrite(bytes, 1, size, fp) != size)
- {
- printf("file append err\n");
- fclose(fp);
- return -1;
- }
- fclose(fp);
- hijackTo(newIPtr);
- //不用RETURN
- }
- void main()
- {
- execMyBytes(code, 21);
- }
复制代码 |
|