进程的创建
进程的启动过程
打开目标exe的映象文件
创建进程内核对象
映射NTDLL到内存
创建线程内核对象
通知子系统对进程进行管理
启动线程初始化空间和加载其他DLL
跳转到入口处开始执行
CreateProcess api
BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
//中文版注释
BOOL CreateProcess(
LPCTSTR lpApplicationName, // 可执行模块名称 (全路径 必须是const字符串
LPTSTR lpCommandLine, // 命令行(字符串 可以不是const字符串
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全描述符
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程描述符
BOOL bInheritHandles, // 继承标志位
DWORD dwCreationFlags, // 创建标志位 (指定控制优先级和创建过程的额外标志,除了如前说,可以在任何组合中指定下列创建标标志
LPVOID lpEnvironment, // 进程环境块
LPCTSTR lpCurrentDirectory, // 驱动目录
LPSTARTUPINFO lpStartupInfo, // 启动信息 指向一个窗体结构,该接口体表示新进程的窗口应该如何出现
LPPROCESS_INFORMATION lpProcessInformation // 进程信息
);
//启动信息参数的结构体
typedef struct _STARTUPINFO {
DWORD cb; //记录指定结构体大小,以字节为单位
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle; //对于控制台进程,日过创建了新的控制欲窗口,则会显示标题栏中的标题,如果NULL。可执行文件额名称将会用作窗口标题, This parameter must be NULL for GUI or console processes that do not create a new console window.
DWORD dwX; //控制窗口位置x
DWORD dwY; //控制窗口位置y
DWORD dwXSize; //控制窗口宽度
DWORD dwYSize; //控制窗口高度
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow; //窗口显示方式
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
//进程信息结构体
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess; //进程句柄
HANDLE hThread; //主线程句柄
DWORD dwProcessId; //被创建的进程id
DWORD dwThreadId; //被创建的主线程ID
} PROCESS_INFORMATION;
exp: 启动qq
……
2018.4.3
2024.12.9
win32
181
1 分钟
窗口与事件
窗口
什么是窗口?
Windows中称为视窗,是一个程序的操作显示界面
窗口执行动作是由什么驱动的?
Windows中通过什么机制将发生的一些动作和响应的响应函数连接起来
……
2018.3.29
2024.12.9
win32
292
1 分钟
API与宽字符
API(Application Programming Interface,应用程序编程接口)
Api的定义
api就是一些预先定义的函数
,目的是提供应用程序与开发人员基于某软件或者硬件的一访问一组例程的能力,而又无需访问源码,或者理解内部工作机制的细节
……
2018.3.28
2024.12.9
win32 /逆向
412
1 分钟
win32中的宽字符
宽字符
数据类型
容器、模板
ASCII
一个字符
一个字节
GB码(扩展了的ASCII)
英文字符
一个字节
GB码
中文字符
两个字节
UNICODE字符集(unicode编码实际指的是utf-16)
常用字符
两个字节
宽字符: 用多个字节来表示的字符称之为宽字符
(只要不是以单字节存储都可称为宽字符)
……
2018.3.27
2024.12.9
win32
361
1 分钟
兼容问题
由于ASCII存在字符含量过少的缺陷,所以不但我国自己搞出了国际码。其他国家也都设计出了符合自己国情的字符集
……
2018.3.27
2024.12.9
win32
361
1 分钟
GB2312原文到GB2312机内码
ANSCII
汉字编码国家标准
区位码
01-09区 为特殊字符区
10-15区 为自定义区
16-87区 为汉字编码区
……
2018.3.1
2024.12.9
CPP
76
1 分钟
模板
下面是一个针对int的冒泡排序
// _20180301.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void Sort(int* arr,int nLength)
{
int i,k;
for (i = 0;ix > base.x && this->y > base.y;
}
private:
int x;
int y;
};
template
void Sort(T* arr,int nLength)
{
int i,k;
for (i = 0;iy)
return x;
else
return y;
}
M min()
{
2018.2.23
2024.12.9
CPP
765
2 分钟
深浅拷贝
相同类型间可以直接拷贝
// _20180212.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
class A
{
private:
int* a;
public:
A()
{
a = new int[10];
}
virtual ~A()
{
delete a;
printf("析构 A \n");
}
};
int main(int argc,char* argv[])
{
A a1;
A a2;
a1 = a2;
return 0;
}
//反汇编
27: A a1;
0040108D lea ecx,[ebp-14h]
00401090 call @ILT+15(B::B) (00401014)
00401095 mov dword ptr [ebp-4],0
28: A a2;
0040109C lea ecx,[ebp-1Ch]
0040109F call @ILT+15(B::B) (00401014)
004010A4 mov byte ptr [ebp-4],1
29: a1 = a2;
004010A8 lea eax,[ebp-1Ch]
004010AB push eax //a2 作为参数传递
004010AC lea ecx,[ebp-14h] //a1 作为this指针传递
004010AF call @ILT+45(A::operator=) (00401032)
30: return 0;
A::operator=:
004012E0 push ebp
004012E1 mov ebp,esp
004012E3 sub esp,44h
004012E6 push ebx
004012E7 push esi
004012E8 push edi
004012E9 push ecx
004012EA lea edi,[ebp-44h]
004012ED mov ecx,11h
004012F2 mov eax,0CCCCCCCCh
004012F7 rep stos dword ptr [edi]
004012F9 pop ecx
//eax = a1首地址
004012FA mov dword ptr [ebp-4],ecx
004012FD mov eax,dword ptr [ebp-4]
//ecx = a2首地址
00401300 mov ecx,dword ptr [ebp+8]
//ecx + 4 这里是 class A中变量a的地址(ecx 对应虚表地址)
//因为ecx是变量a2 所以这里的edx = a2.a
00401303 mov edx,dword ptr [ecx+4]
//a2.a 赋值给a1.a
00401306 mov dword ptr [eax+4],edx
//返回a1首地址
00401309 mov eax,dword ptr [ebp-4]
0040130C pop edi
0040130D pop esi
0040130E pop ebx
0040130F mov esp,ebp
00401311 pop ebp
00401312 ret 4
我们发现使用=
直接赋值对象,编译器自动生成了operator=
函数用于处理类型赋值
我们观察编译器自动生成的函数operator=
,这里赋值直接略过了虚表(ecx+4)
……
2018.2.20
2024.12.9
ruby
204
1 分钟
Agenda
Loop
Expression
File Read/Write
Debug
Process & Thread
Loop
while
a = 10
while a > 0
puts a
a -= 1
end
until
a = 100
until a == 0
puts a
a -= 1
end
loop
a = 10
loop do
break if a 0
!~
正则匹配 是否匹配不到 匹配到返回fals 匹配不到返回true
……