本帖最后由 群发软件 于 2017-6-25 20:03 编辑
最近也在学着修改Gh0st远控的源代码,源代码免杀起来还是方便、简单、有效和简单点。针对于输入输出表盯的比较紧的杀毒软件,最有效的还是进行函数动态调用。也就是说找到函数的原定义,包括值类型和参数等等,再在调用该函数的地方重新定义这个函数,其实也只是改下函数名而已,下面举个例子:
CreateRemoteThread 作用是创建远线程,假设杀毒软件现在就杀在这个函数上,我们就这样处理,首先在代码中右键点击CreateRemoteThread函数-->转到定义,找到函数的原型:
函数原型如下:
WINBASEAPI
__out
HANDLE
WINAPI
CreateRemoteThread(
__in HANDLE hProcess,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);
改后的函数模型如下:
typedef HANDLE (WINAPI *CreateRemoteThreadxx)
(
__in HANDLE hProcess,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);
CreateRemoteThreadxx yyCreateRemoteThread= (CreateRemoteThreadxx)GetProcAddress(LoadLibrary("kernel32.dll"),"CreateRemoteThread");
补充:有些函数原型最后面分别带得有A和W的,如果你的编译环境是ANSI环境就选择带A的那部分,如果你的环境是Unicode环境,那就选择带W的那部分。例如:GetUserName的原型有两种定义:GetUserNameA和GetUserNameW,视实际情况选择相应的函数原型进行修改就好。
修改后调用的函数名就由CreateRemoteThread变为了yyCreateRemoteThread,红色部分为自定义部分,随便你改称什么,但是要注意前后一致。蓝色的部分再可以用字符串连接法进行分离后连接,这样处理之后,杀毒软件就找不到CreateRemoteThread这个函数了。到此,文件的这处也就免杀了。一点小手记,分享给大家,见笑了。
后记:看了很多教程,都是说怎么改,没说为什么要这么改,也没说还可以怎么改,更没说改的限度是什么。一看教程里先在函数后面加个L,再在定义后的新的函数前面加个p,接着很多看了教程的人都改成那两个,做教程的人还在教程里吓唬人说“别的都不要动,这两个地方改成这样就可以了”,有时候有些事情并不难,并不可怕,难和可怕大多来自于别人的耸人听闻和对未知事物的惧怕。最后希望大家都能够放开手脚,干番大事业!搞了个垃圾站赚点外块,希望大家能支持下。
码免杀,我认为是比较高层次的免杀技术了,大家如果一点免杀基础都没有,学起来应该会很吃力。
源码免杀的好处很多,像函数的动态调用就彻底的解决了以为追杀的问题,加点花就过很多杀软,等等,优势非常多。而且过主动等等都要用到源码的知识。
希望刚开始学习源码免杀的朋友,顺便也学习一下C++的相关基础知识。
1.学习源码免杀需不需要VC++基础?
其实需要是需要一点,但是没有基础一样可以免杀。要想深入学习,必须要下苦功夫了。首先说一下,我就是无C++基础学的免杀,现在在补习C++基础。
2.源码免杀所用到的工具
VC++ 6.0
以下地址复制到迅雷
thunder://QUFodHRwOi8veGlhemFpLnhpYXphaWJhLmNvbS9Tb2Z0L1YvVkMrK182LjBfWGlhWmFpQmEuemlwWlo=/
SDK库:
源码花指令: __asm
{
NOP
NOP
NOP
}
这个相当于汇编免杀里面的NOP指令,没有实际作用的意思
字符串的免杀方法:
/把字符串"#32770"连接起来(字符串连接法) char *str1="#32", *str2="770",*str3=NULL; str3=new char[strlen(str1)+strlen(str2)+1]; strcpy(str3,str1); //把str1所指由NULL结束的字符串复制到str3所指的数组中 strcat(str3,str2); //把str2所指字符串添加到str3结尾处(覆盖dest结尾处的'\0')并添加'\0' //这样就实现了str3=str1+str2,把str1和str2连接起来了
字符串的隐藏 字符串隐藏 char XXX[] = {'l','s','t','r','l',e', 'n', 'a','\0'};
最近没什么心情写博客,似乎停止不前了,唉,越来越懒了,不知道怎么回事,整理以前的笔记,这个免杀的,不知道内容过时了没。
各个杀毒软件查杀特点不一样,大致总结以下,API函数,字符串,代码段,资源段。免杀方法大致有如下几种手段,动态函数调用,延迟加载DLL,合并区段,字符串隐藏,删版权换版权,花指令,反调试等等细节,以上几种方法基本上过掉大部分杀软,当然有能力也可以自己改变程序的代码实现原来的功能。
1.动态函数调用
有两个函数是不能调用的,GetProcAddress,LoadLibrary。
杀毒软件如果查杀到API函数上,可以用动态函数调用解决。
typedef int (WINAPI *MessageBoxAT)
(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType
);
MessageBoxAT pMessageBoxA= (MessageBoxAT)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA");
2.字符串隐藏
利用数组来隐藏,字符串处理相对比较简单,隐藏的办法有很多,举出一种吧。
char name[]={'a','b','c','/0'};
name替换掉原来的字符串.
3.延迟加载DLL
源代码上加上,或者写成头文件加上也可以.
#pragma comment(linker, "/OPT:NOWIN98")
#pragma comment(lib, "DELAYIMP.LIB")
#pragma comment(linker, "/DELAYLOAD:WININET.dll")
#pragma comment(linker, "/DELAYLOAD:WS2_32.dll")
#pragma comment(linker, "/DELAYLOADSAPI.DLL")
#pragma comment(linker, "/DELAYLOAD:GDI32.dll")
#pragma comment(linker, "/DELAYLOAD:ADVAPI32.dll")
#pragma comment(linker, "/DELAYLOAD:SHELL32.dll")
#pragma comment(linker, "/DELAYLOAD:WINMM.dll")
#pragma comment(linker, "/DELAYLOAD:USER32.dll")
#pragma comment(linker, "/DELAYLOAD:WTSAPI32.dll")
#pragma comment(linker, "/DELAYLOAD:AVICAP32.dll")
#pragma comment(linker, "/DELAYLOAD:SHLWAPI.dll")
#pragma comment(linker, "/DELAYLOAD:MSVFW32.dll")
#pragma comment(linker, "/DELAY:nobind")
#pragma comment(linker, "/DELAY:unload")
4.合并区段
把其他区段合并到一个区段里,以前这个方法还管用,可以试试,但最好不要加。
#pragma comment(linker, "/MERGE:.rdata=.data")//把rdata区段合并到data区段里
#pragma comment(linker, "/MERGE:.text=.data")//把text区段合并到data区段里
#pragma comment(linker, "/MERGE:.reloc=.data")//把reloc区段合并到data区段里
4 .删版权资源
有时对版权也查杀,可以换版权或者删除。
5.花指令
如果杀在代码段上可以加NOP来打乱程序的位置,一般不要加太多,有时也会查杀NOP。
__asm nop;
__asm nop;
__asm nop;
5.反调试
HKEY ck;
char strreg[] = {'S','O','F','T','W','A','R','E','//','O','D','B','C','/0'};
if(ERROR_SUCCESS!=RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)strreg,0,KEY_ALL_ACCESS,&ck))
{
return 0;
}
6.代码换位
定位到特征码后,看代码中的程序是否可以代码换位。
注意的细节:
定位360BD引擎的时候,找到入口点,填充入口点以上的代码,查杀,如果免杀,就说明在这一区段.
map文件定位:
用OD找代码的时候,有时上下没有参考,可以用map文件来帮助,在VC6.0中设置map文件,然后拿出来,用OD里面的一个插件loadmap,载入map,重新运行,就可以了.