堆溢出
作者:admin 日期:2010-08-15
你的症状是因为你浏览的页面的脚本中的函数出现了过度的递归调用,比如递归了4096次,然后就溢出了
一、堆溢出后的后果;
现在的系统管理堆,为了查询的高效快速,一般都使用的双向链表结构。我们来看
双向链表管理的时候的删除操作。*a,*b,*p1,*p2,*c,*d都是指针,考虑双向链表,
a,b--->p1,p2--->c,d,其中由双向链表有*b=p1,*p1=a,*p2=c。如果是空闲内存链表,
那么申请使用p1、p2指向的内存,或者如果是使用内存链表,释放p1、p2指向的内存,
都会从这个链表中删除p1,p2。删除后的链表是a,b--->c,d,应该有内存改写操作:
*b=c,*c=a。这时代码是经过链表检索从a,b得到的p1,p2,一般为了高效等就不会记忆
a,b,因为双向链表就是为了从一个结点可以方便的得到上级和下级结点。所以那两条
内存操作都将会转换成p1、p2相关的操作。根据前面得到的信息,经过简单的代换就可
以得到我们需要的代码:
VC实现PPPOE拨号
作者:admin 日期:2010-08-02
另外我还发现闪讯拨号用的现成的api,ras函数。这也否定了我以前的一个猜想。我现在强烈感觉到那串加在用户名前面的不明数据就是一串随即数据。ras函数我不熟,网上找了一个简单的pppoe例子,先放着以后说不定用得着。
废话到此结束。
背景:代替手工自动进行PPPOE拨号
相关知识:
主要使用的函数:
The RasDial function establishes a RAS connection between a RAS client and a RAS server. The connection data includes callback and user-authentication information
DWORD RasDial(
__in LPRASDIALEXTENSIONS lpRasDialExtensions,
__in LPCTSTR lpszPhonebook,
__in LPRASDIALPARAMS lpRasDialParams,
__in DWORD dwNotifierType,
__in LPVOID lpvNotifier,
__in LPHRASCONN lphRasConn
);
Return Value
base64编码/解码函数 c语言
作者:admin 日期:2010-07-15
CreateProcess实例和TerminateProcess实例
作者:admin 日期:2010-07-15
这个实例编写了两个函数,分别叫做shell和kill(用到的api分别是CreateProcess和,TerminateProcess).shell函数的参数是一个你要执行的可执行文件的名称,当然只要文文件格式符合exe的pe格式就可以(比如你可以把一个calc.exe改名为calc.jpg用这个函数照样可以执行),然后他返回新创建的这个进程的pid。
第二个函数的作用是结束一个进程,你只须传入这个进程的pid即可。若成功返回true, 否则返回false。
很简单吧。
#include <windows.h>
宽字符处理函数函数与普通函数对照表
作者:admin 日期:2010-07-10
HTTP协议详解
作者:admin 日期:2010-06-05
HTTP 是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系 的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时 间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这 样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
VC实现将资源打包并释放到指定文件夹
作者:admin 日期:2010-05-26
很多安装程序或者比较高级点的智能程序都已经这样做,比如文件损坏时,安装程序将修复这些文件.一些高级程序的常用设置及文件
遇到破坏时, 也会自我修复,它们的这些神奇功能,全都是依靠自身的资源包,替换损坏的文件,或者创建新的默认文件实现的.
下面我来说一说这种程序比较普通的一些做法:
首先在程序入口处,我们以MFC程序为例子,我们找到APP文件,在InitInstance()中执行文件检查, 如果发现某些文件损坏或者不存在,
那么我们将自身资源包的正常文件释放出来,在这里我给出两个函数,一个是检查指定文件是否存在,另一个是释放资源包文件的函数.
BOOL FileExteriorFile(LPCTSTR FileName)//查找指定的文件是否存在
{
WIN32_FIND_DATA fd;
HANDLE hd=::FindFirstFile(FileName,&fd);//开始查找
if(hd==INVALID_HANDLE_VALUE)
{
return FALSE;
}
FindClose(hd);//关闭查找
return TRUE;
}
发现不存在时,将调用下面的函数释放资源包的文件
//将指定资源释放到指定目录下生成特定文件
BOOL FreeMyData(LPCTSTR ResName, LPCTSTR ResType, LPCTSTR FileName, int Type)
{
BOOL bRet = TRUE;
HINSTANCE hInst = AfxGetInstanceHandle();
//先判断我们指定的资源是否存在
HRSRC hResInfo = FindResource(hInst,ResName,ResType);
if(hResInfo == NULL)
return FALSE;
HANDLE hFile = NULL;
DWORD dwWritten = 0;
// 开始调入指定的资源到内存
HGLOBAL hResData = LoadResource(hInst,hResInfo);
LPVOID pvResData = LockResource(hResData);
DWORD dwResSize = SizeofResource(hInst,hResInfo);
//再创建目标文件并保存数据至文件
if(Type == 1)//系统加隐藏属性 如果指定类型为1,那么加上系统和隐藏属性,防止普通用户对文件进行破坏
{
hFile = CreateFile(FileName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_Delete,
NULL,Create_ALWAYS,FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, NULL);
WriteFile(hFile, pvResData, dwResSize, &dwWritten, NULL);
}
else
{
hFile = CreateFile(FileName,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_Delete,
NULL,Create_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, pvResData, dwResSize, &dwWritten, NULL);
}
if(hFile == INVALID_HANDLE_VALUE)//创建文件失败
{
FreeResource(hResData);
return FALSE;
}
//释放有关内存资源
CloseHandle(hFile);
FreeResource(hResData);
return TRUE;
}
将上面两个函数COPY到你工程的APP文件中,现在假设你已将一个 Demo.dat文件通过资源映射导入工程当中,类型属于ExFile,文件名是IDR_EXFILE1,
那么你在 InitInstance()中的调用形式如下:
if(!FileExteriorFile(FileName))//注意:FileName是你指定目录下的指定文件
{
if(!FreeMyData(MAKEINTRESOURCE(IDR_EXFILE1), "ExFile", FileName,0))//释放文件到指定目录
{
MessageBox(NULL,FileName,"Free File Fail:",MB_ICONERROR);
}
}
这样你就已实现了将资源包释放出来替换或者覆盖某些文件的目的,你可以释放的文件类型可以是EXE文件,DLL文件等等.
在编写该程序的过程当中,我还加入了很多特殊的功能,比如释放出一个新的EXE文件,然后执行,再把自身销毁,这个时候杀毒程序警告我,这是一个病毒,
哈哈,可能病毒就是这样的搞的.那么你还等什么,赶快试试吧.
c语言winsock 实现域名解析
作者:admin 日期:2010-05-16
Console Functions
作者:admin 日期:2010-05-16
The following functions used to access a console.
AllocConsole
CreateConsoleScreenBuffer
FillConsoleOutputAttribute
FillConsoleOutputCharacter
FlushConsoleInputBuffer
FreeConsole
GenerateConsoleCtrlEvent
GetConsoleCP
GetConsoleCursorInfo
GetConsoleMode
GetConsoleOutputCP
GetConsoleScreenBufferInfo
GetConsoleTitle
GetLargestConsoleWindowSize
GetNumberOfConsoleInputEvents
GetNumberOfConsoleMouseButtons
GetStdHandle
HandlerRoutine
PeekConsoleInput
ReadConsole
ReadConsoleInput
ReadConsoleOutput
ReadConsoleOutputAttribute
ReadConsoleOutputCharacter
ScrollConsoleScreenBuffer
SetConsoleActiveScreenBuffer
SetConsoleCP
SetConsoleCtrlHandler
SetConsoleCursorInfo
SetConsoleCursorPosition
SetConsoleMode
SetConsoleOutputCP
SetConsoleScreenBufferSize
SetConsoleTextAttribute
SetConsoleTitle
SetConsoleWindowInfo
SetStdHandle
WriteConsole
WriteConsoleInput
WriteConsoleOutput
WriteConsoleOutputAttribute
WriteConsoleOutputCharacter
网络字节换函数
作者:admin 日期:2010-05-15
socket编程时网络传输数据必须转换为网络字节序,而且不管IP是哪种字节序系统识别都必须为unsigned long型,点分式IP仅方便记忆,下面介绍一些常用转换函数。
函数原型:unsigned long inet_addr( const char* cp ); 将char*类型转换为网络字节顺序,返回32位的unsigned long型,例addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");其中addrSrv是套接字对象。
函数原型:char* FAR inet_ntoa( struct in_addr in ); 参数为in_addr结构体,返回点分格式的IP地址。
函数原型:u_long htonl( u_long hostlong );
c++ new详解
作者:admin 日期:2010-04-26
Keyboard Hook
作者:admin 日期:2010-04-20
A DLL is an indirectly executable which doesn't have a message loop to receive user input. DLLs are seperate files containing functions(not only) that can be called by programs and other DLLs. To the end-user a DLL is a program that can't be executed directly from the Program Manger(or other Shells), but from the system's point of view, there are two differences between DLLs and applications: DLLs cannot have multiple running instances loaded in memory. and DLLs attach themselves to processes, only application instances are processes. DLL stands for Dynamic-Link Library. Dynamic-Link is a mechanism to link libraries to applications at run time. These libraries(DLLs) reside in their own executable files(.dll) and are not copied into applications' executable files(.exe) as with Static-Link libraries. It's important to understand that a .DLL is loaded into the address space of the specified linking application and not into the global heap! The advantages of using dynamic linking method are:
They can be updated without requiring applications to be recompiled or relinked.
When several applications use the same .DLL, the .DLL is just loaded once for all applications(reducing memory and disk space).
VC++网络编程
作者:admin 日期:2010-04-17
VC++对网络编程的支持有socket支持,WinInet支持,MAPI和ISAPI支持等。其中,Windows Sockets API是TCP/IP网络环境里,也是Internet上进行开发最为通用的API。最早美国加州大学Berkeley分校在UNIX下为TCP/IP协议开发了一个API,这个API就是著名的Berkeley Socket接口(套接字)。
在桌面操作系统进入Windows时代后,仍然继承了Socket方法。在TCP/IP网络通信环境下,Socket数据传输是一种特殊的I/O,它也相当于一种文件描述符,具有一个类似于打开文件的函数调用-socket()。
可以这样理解:Socket实际上是一个通信端点,通过它,用户的Socket程序可以通过网络和其他的Socket应用程序通信。Socket存在于一个“通信域”(为描述一般的线程如何通过Socket进行通信而引入的一种抽象概念)里,并且与另一个域的Socket交换数据。Socket有三类。第一种是SOCK_STREAM(流式),提供面向连接的可靠的通信服务,比如telnet,http。第二种是SOCK_DGRAM(数据报),提供无连接不可靠的通信,比如UDP。第三种是SOCK_RAW(原始),主要用于协议的开发和测试,支持通信底层操作,比如对IP和ICMP的直接访问。
二、Windows Socket机制分析
SendMessage()函数详解
作者:admin 日期:2010-04-13
举个例子,打开记事本程序,该程序有一个 “文件“菜单。 那么,在运行该程序的时候,如果用户单击“文件菜单“里的“新建“命令, 这个动作将被Windows所捕捉,Windows经过分析得知这个动作应该由我们打开的记事本程序所来处理,然后Windows就发送个消息 譬如我们编程的时候有时用到的 WM_COMMAND的消息给记事本,然后记事本就把这个消息处理掉。 这个过程就是消息处理。
接下来,我们把 SendMessage的完整形式讲一下SendMessage
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
别名
c++ 内存加载exe
作者:admin 日期:2010-04-13
api hook和pe格式的关系
作者:admin 日期:2010-04-13
假设我们已经了解了pe格式,那么我们在哪里修改api的函数入口点比较合适呢?这个就是输入符号表imported symbols table(间接)指向的输入符号地址。
下面对于pe格式的介绍这一部分,对于没有接触过pe格式学习的朋友应该是看不太明白的,但我已经把精华部分提取出来了,学习了pe格式后再看这些就很容易了。
pe格式的基本组成
+-------------------+
| DOS-stub | --DOS-头
+-------------------+
| file-header | --文件头
+-------------------+
| optional header | --可选头
|- - - - - - - - - -|
| |
| data directories | --(可选头尾的)数据目录
| |
+-------------------+
| |
| section headers | --节头
| |
+-------------------+
| |
| section 1 | --节1
| |
+-------------------+
| |
| section 2 | --节2
| |
+-------------------+
| |
| ... |
| |
+-------------------+
| |
| section n | --节n
| |
+-------------------+
在上图中,我们需要从“可选头”尾的“数据目录”数组中的第二个元素——输入符号表的位置,它是一个IMAGE_DATA_DIRECTORY结构,从它中的VirtualAddress地址,“顺藤摸瓜”找到api函数的入口地点。
下图的简单说明如下:
OriginalFirstThunk 指向IMAGE_THUNK_DATA结构数组,为方便只画了数组的一个元素,AddressOfData 指向IMAGE_IMPORT_BY_NAME结构。
IMAGE_IMPORT_DESCRIPTOR数组:每个引入的dll文件都对应数组中的一个元素,以全0的元素(20个bytes的0)表示数组的结束
IMAGE_THUNK_DATA32数组:同一组的以全0的元素(4个bytes的0)表示数组的结束,每个元素对应一个 IMAGE_IMPORT_BY_NAME结构
IMAGE_IMPORT_BY_NAME:如..@Consts@initialization$qqrv. 表示
Unmangled Borland C++ Function: qualified function __fastcall Consts::initialization()
为了减少这个图的大小,不得已将汇编和c++的结构都用上了。这个图是输入符号表初始化的情形,此时两个IMAGE_THUNK_DATA结构数组的对应元素都指向同一个IMAGE_IMPORT_BY_NAME结构。
程序加载到进程空间后,两个IMAGE_THUNK_DATA结构数组指向有所不同了。看下图:
// 本文转自 C++Builder研究 - http://www.ccrun.com/article.asp?i=1036&d=cf6de2
始化的,“两个结构都指向同一个IMAGE_IMPORT_BY_NAME”,此时还没有api函数地址
当PE文件准备执行时,前图已转换成上图。一个结构指向不变,另一个出现api函数地址
如果PE文件从kernel32.dll中引入10个函数,那么IMAGE_IMPORT_DESCRIPTOR 结构的 Name1域包含指向字符串"kernel32.dll"的RVA,同时每个IMAGE_THUNK_DATA 数组有10个元素。(RVA是指相对地址,每一个可执行文件在加载到内存空间前,都以一个基址作为起点,其他地址以基址为准,均以相对地址表示。这样系统加载程序到不同的内存空间时,都可以方便的算出地址)
上述这些结构可以在winnt.h头文件里查到。