首页
社区
课程
招聘
[原创]一个编译器含源码,基于luocong大神的lcc改进而成
2015-3-3 16:45 11713

[原创]一个编译器含源码,基于luocong大神的lcc改进而成

2015-3-3 16:45
11713
hi,各位新年快乐~拜个晚年

大概前年底的时候,开始想往自制的os tinix里移植一个编译器,构建一个传说中的os生态,哈哈
于是看雪上面找来luocong大神的lcc源码进行研究,改着改着发现要移植是不可能的事情。
但是研究的过程中发现了lcc源码的不少问题,也有了一些功能改进想法和研究兴趣,顺便也想了解下编译原理这门学科。慢慢的做了好多现在看来很2的修改。

也许可以改进成一个不错的脚本解释器,发出来大家一起研究学习下

luocong大神的lcc在这个帖子上
http://bbs.pediy.com/showthread.php?t=149966
分发遵循BSD协议,有改进也可以共享下

做了很多修改,大多是为了实现A功能首先得实现B功能,实现期间发现,干脆再实现个C功能......
由于是很早以前改的,忘了很多,印象里做了以下几点修改:
1,修复部分语法解析上的bug,不赘述,可通过查看两份代码区别来确认。

2,新增一部分语法支持,如取地址符,指针符,全局变量等。这部分主要实现在,虚拟机指令的修改,代码生成时全局内存分配的修改。

3,为虚拟机添加调试功能
启动时-d参数将进入调试模式,调试器将停在第一条虚拟指令li_i指令上

断点功能(支持符号)及调用栈查看、内存查看等功能



4,可变参数调用约定的支持

5,define宏的简单支持

#define MUL(_a,_b,_c) ((_a)*(_b)*(_c))


6,在脚本解释器和vc run-time library之间做了一层转发stub,因为这个虚拟机也是通过栈传参,所以这个转发实现的比较简单。这层转发也依靠上述的define宏支持和可变参数的支持。

定义宏
#define CRT_LIB_NAME "msvcr90.dll"
#define malloc(_size) cdecl_wrapper(CRT_LIB_NAME, "malloc", _size)

代码中的malloc(100)将被展开为
cdecl_wrapper("msvcr90.dll", "malloc", 100)

cdecl_wrapper的实现如下

INT cdecl_wrapper( CONST CHAR *libname, CONST CHAR *funname, PINT sp, INT ParamSize )
{
    HMODULE hLib = NULL;
    PVOID pFn = NULL;
    INT retvalue = 0;
    INT nParamCount = ParamSize / sizeof_i - 2;
    INT nParamSize = ParamSize - sizeof_i*2;
    PINT pParam = &sp[2+nParamCount];

    hLib = GetModuleHandle(libname);
    if (hLib == NULL)
        hLib = LoadLibrary(libname);

    if (hLib == NULL)
    {
        VM_Error(emVEI_Runtime_Error_Can_not_find_library_x, libname);
        return 0;
    }

    pFn = (PVOID)GetProcAddress(hLib, funname);
    if (pFn == NULL)
    {
        VM_Error(emVEI_Runtime_Error_Can_not_find_method_x_in_x, funname, libname);
        return 0;
    }

    __try
    {
        __asm
        {
            pusha
            mov     eax, pParam
            mov     ecx, nParamCount
l1:
            cmp     ecx, 0
            je      l2
            mov     ebx, [eax]
            push    ebx
            sub     eax, 4
            dec     ecx
            jmp     l1
l2:
            call    pFn
            mov     retvalue, eax
            add     esp, nParamSize
            popa
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        VM_Error(emVEI_Runtime_Error_An_exception_occurs_during_libcall_x, funname);
    }

    //FreeLibrary(hLib);
    return retvalue;
}

使用这个简单的转发,可以直接调用msvcrt中的大部分函数。
如crt.h脚本头文件中定义的
//mem
#define malloc(_size) cdecl_wrapper(CRT_LIB_NAME, "malloc", _size)
#define free(_buff)   cdecl_wrapper(CRT_LIB_NAME, "free", _buff)
#define memset(_buff, _set, _size) cdecl_wrapper(CRT_LIB_NAME, "memset", _buff, _set, _size)
#define memmove(_dest, _src, _count) cdecl_wrapper(CRT_LIB_NAME, "memmove", _dest, _src, _count)
#define memcpy(_dest, _src, _count) cdecl_wrapper(CRT_LIB_NAME, "memcpy", _dest, _src, _count)
#define memchr(_buff, _ch, _count) cdecl_wrapper(CRT_LIB_NAME, "memmove", _buff, _ch, _count)
#define memcmp(_dest, _src, _count) cdecl_wrapper(CRT_LIB_NAME, "memcmp", _dest, _src, _count)


//file
/* Seek method constants */
#define SEEK_CUR    1
#define SEEK_END    2
#define SEEK_SET    0
#define fopen(_path, _mode) cdecl_wrapper(CRT_LIB_NAME, "fopen", _path, _mode) 
#define fclose(_stream) cdecl_wrapper(CRT_LIB_NAME, "fclose", _stream)
#define feof(_stream) cdecl_wrapper(CRT_LIB_NAME, "feof", _stream)
#define ftell(_stream) cdecl_wrapper(CRT_LIB_NAME, "ftell", _stream)
#define fseek(_stream, _offset, _fromwhere) cdecl_wrapper(CRT_LIB_NAME, "fseek", _stream, _offset, _fromwhere)
#define fread(_buffer, _size, _count, _stream) cdecl_wrapper(CRT_LIB_NAME, "fread", _buffer, _size, _count, _stream)
#define fwrite(_buffer, _size, _count, _stream) cdecl_wrapper(CRT_LIB_NAME, "fwrite", _buffer, _size, _count, _stream)


//string
#define strcpy(_dest, _src) cdecl_wrapper(CRT_LIB_NAME, "strcpy", _dest, _src)
#define strncpy(_dest, _src, _count) cdecl_wrapper(CRT_LIB_NAME, "strncpy", _dest, _src, _count)
#define strcat(_dest, _src) cdecl_wrapper(CRT_LIB_NAME, "strcat", _dest, _src)
#define strncat(_dest, _src, _count) cdecl_wrapper(CRT_LIB_NAME, "strncat", _dest, _src)
#define strcmp(_cs, _ct) cdecl_wrapper(CRT_LIB_NAME, "strcmp", _cs, _ct)
#define strncmp(_cs, _ct, _count) cdecl_wrapper(CRT_LIB_NAME, "strncmp", _cs, _ct, _count)
#define strchr(_s, _c) cdecl_wrapper(CRT_LIB_NAME, "strchr", _s, _c)
#define strrchr(_s, _c) cdecl_wrapper(CRT_LIB_NAME, "strrchr", _s, _c)
#define strspn(_cs, _ct) cdecl_wrapper(CRT_LIB_NAME, "strspn", _cs, _ct)
#define strcspn(_cs, _ct) cdecl_wrapper(CRT_LIB_NAME, "strcspn", _cs, _ct)
#define strpbrk(_cs, _ct) cdecl_wrapper(CRT_LIB_NAME, "strpbrk", _cs, _ct)
#define strstr(_cs, _ct) cdecl_wrapper(CRT_LIB_NAME, "strstr", _cs, _ct)
#define strlen(_s) cdecl_wrapper(CRT_LIB_NAME, "strlen", _s)
#define strtok(_s, _ct) cdecl_wrapper(CRT_LIB_NAME, "strtok", _s, _ct)
#define strtol(_nptr, _endptr, _base) cdecl_wrapper(CRT_LIB_NAME, "strtol", _nptr, _endptr, _base)


如通过这层转发调用crt的fopen、fprintf函数进行简单的文件操作
脚本源码
#include "crt.h"

int main()
{
    int f = fopen("out.txt","w");
    fprintf(f, "测试数据");
    fclose(f);
    
    return 0;
}




这层转发大大的增加了脚本实现各种功能的可能性,可以自由发挥想象,比如座一层stdcall约定的转发,调用个MessageBox也不是太难的事情。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 3
打赏
分享
最新回复 (11)
雪    币: 435
活跃值: (1167)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
bitt 5 2015-3-3 16:52
2
0
另外,-p的虚拟指令修改也做了点修改,让他能做出一些注释来
这种基于符号的注释和上贴中的变量功能,都是通过编译期间的 符号表 和运行期间共享实现的


有点OD的感觉了~
哈哈
上传的附件:
雪    币: 341
活跃值: (133)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 2 2015-3-3 18:24
3
0
好厉害膜拜
雪    币: 100
活跃值: (323)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Arcade 2015-3-3 18:31
4
0
膜拜。。
雪    币: 135
活跃值: (64)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
fatecaster 1 2015-3-3 18:39
5
0
mark
雪    币: 155
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yxwdjsw 2015-3-3 19:02
6
0
我都不好意思回复了,注册那么早的,技术现在要用想起来要学习了,希望能跟上LZ
雪    币: 80
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
iforgiven 2015-3-3 20:23
7
0
可以看看tcc。
雪    币: 74
活跃值: (638)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wodexinren 2015-3-3 20:27
8
0
高端,膜拜
雪    币: 435
活跃值: (1167)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
bitt 5 2015-3-3 22:03
9
0
当时不能用tcc的,对libc的依赖太深了,无法移植
还是lcc好,依赖少,不过还是没成功移植就是了
雪    币: 85
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
grusirna 1 2015-3-4 00:08
10
0
强悍的讲话~
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dppdpp 2015-3-5 00:14
11
0
挺好,有机会合作。
雪    币: 108
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
edaboy 2015-3-7 10:05
12
0
谢谢,正在弄这个
游客
登录 | 注册 方可回帖
返回