Asura 的笔记本 https://luodaoyi.com/ zh-CN 编程比吸毒还要上瘾 Fri, 15 Jun 2018 12:33:00 +0800 Fri, 15 Jun 2018 12:33:00 +0800 ubuntu 搭建S3服务 mino单机和集群集群 https://luodaoyi.com/p/ubuntu-set-up-s3-services-mino-single-machine-and-cluster-cluster.html https://luodaoyi.com/p/ubuntu-set-up-s3-services-mino-single-machine-and-cluster-cluster.html Fri, 15 Jun 2018 12:33:00 +0800 luodaoyi 搭建mino 集群

单机版

# 新建用户
sudo useradd -r minio-user -s /sbin/nologin
sudo chown -R minio-user:minio-user /usr/local/bin/minio

sudo mkdir /usr/local/share/minio
sudo chown -R minio-user:minio-user /usr/local/share/minio


sudo mkdir /etc/minio
sudo chown -R minio-user:minio-user /etc/minio

# 记得替换 MINIO_VOLUMES
cat <<EOT >> /etc/default/minio
# Local export path.
MINIO_VOLUMES="/tmp/minio/"
# Use if you want to run Minio on a custom port.
MINIO_OPTS="--address :443"

EOT

# 替换key
cat <<EOT >> /etc/default/minio
# Access Key of the server.
MINIO_ACCESS_KEY=Server-Access-Key
# Secret key of the server.
MINIO_SECRET_KEY=Server-Secret-Key

EOT

# 下载安装service文件
( cd /etc/systemd/system/; curl -O https://raw.githubusercontent.com/minio/minio-service/master/linux-systemd/minio.service )

# 记得替换 /etc/systemd/system/minio.service
# 中user和group

# 重载配置
systemctl daemon-reload
# 开机启动
systemctl enable minio.service

systemctl disable minio.service

集群版本

# 新建用户
useradd minio-user -s /sbin/nologin

# 记得替换 MINIO_VOLUMES
$ cat <<EOT >> /etc/default/minio
# Remote node configuration.
MINIO_VOLUMES=http://node1/export1 http://node2/export2 http://node3/export3 http://node4/export4
# Use if you want to run Minio on a custom port.
MINIO_OPTS="--address :9199"

EOT

# 替换key

cat <<EOT >> /etc/default/minio
# Access Key of the server.
MINIO_ACCESS_KEY=Server-Access-Key
# Secret key of the server.
MINIO_SECRET_KEY=Server-Secret-Key

EOT

# 下载安装service文件

( cd /etc/systemd/system/; curl -O https://raw.githubusercontent.com/minio/minio-service/master/linux-systemd/distributed/minio.service )

# 记得替换 /etc/systemd/system/minio.service
# 中user和group

# 重载配置
systemctl daemon-reload
# 开机启动
systemctl enable minio.service

systemctl disable minio.service
systemctl restart minio.service

# 查看日志
journalctl -u nginx.service -f 

配置ssl证书

/home/minio/.minio/certs

# 安装acme.sh
 apt-get install libcurl4-openssl-dev
 curl https://get.acme.sh | sh

# 配置好dns

export CF_Email="xxxx"
export CF_Key="xxx”

# 申请ssl
acme.sh --issue --dns dns_cf -d xx.com -d *.xx.com

acme.sh  --installcert  -d  xxx.com   \
        --key-file   /home/minio-user/.minio/certs/private.key \
        --fullchain-file /home/minio-user/.minio/certs/public.crt \
        --reloadcmd  "systemctl restart minio.service"

最后切换到ssl模式

vim /etc/default/minio

# 修改端口
MINIO_OPTS="--address :443"

# 重启服务器
systemctl restart minio.service
]]>
1 https://luodaoyi.com/p/ubuntu-set-up-s3-services-mino-single-machine-and-cluster-cluster.html#comments https://luodaoyi.com/feed/p/ubuntu-set-up-s3-services-mino-single-machine-and-cluster-cluster.html
简单的GDI操作 https://luodaoyi.com/p/simple-gdi-operation.html https://luodaoyi.com/p/simple-gdi-operation.html Tue, 29 May 2018 03:01:12 +0800 luodaoyi 简单的GDI操作

窗口程序的本质 :GUI GDI

GDI: Graphics Device Interface,图形设备接口,这是Windows提供的一组用于绘制图像的API
GUI: Graphical User Interface,图形用户界面,是指用户操作软件的界面方式,以区别于字符方式

说白了 GDI是一套实打实的接口,真实存在 GUI只是一个概念

GDI 图像设备接口(Graphics Device Interface)

  1. 设备对象(HWND)
  2. DC(设备上下文,Device Contexts)
  3. 图形对象
图形对象作用
画笔(Pen)影响线条,包括颜色、粗细、虚实、箭头形状等
画刷(Brushes)影响对形状、区域等操作,如使用的颜色、是否有阴影等
字体(Fonts)影响文字输出的字体
位图(Bitmaps)影响位图创建、位图操作和保存等。

相关API

  • 上下文相关:

    `GetDC`       =>  获取上下文
    `ReleaseDC`   =>  释放上下文
    
  • 线条相关:

    `MoveToEx/LineTo` => 绘制直线
    `SetPixel/Getpixel` 
    
  • 绘制封闭图形

    `Rectangle`   => 绘制矩形
    `Ellipse`     => 绘制圆形
    `RoundRect`   => 绘制圆角矩形
    

demo

https://github.com/luodaoyi/cpp_code/tree/master/MemoryInjectTool/GDI

]]>
0 https://luodaoyi.com/p/simple-gdi-operation.html#comments https://luodaoyi.com/feed/p/simple-gdi-operation.html
消息机制与模拟消息 https://luodaoyi.com/p/message-mechanism-and-analog-message.html https://luodaoyi.com/p/message-mechanism-and-analog-message.html Tue, 29 May 2018 01:50:14 +0800 luodaoyi 消息机制与模拟消息

消息机制

  • 硬件产生事件
  • 被操作系统捕获,封装成消息
  • 操作系统发送到系统消息队列
  • 再由操作系统由系统消息队列发送到 对应的线程内核对象中的线程消息队列
  • 线程消息队列处理完毕后,将时间送回操作系统
  • 由操作系统调用窗口回调函数 => WindowProc()

线程消息队列 处理

  • GetMessage() => 取出消息
  • DispathMessage() => 把消息再送回系统中系统中

在线程拿到消息之前,消息经过了两个队列

  1. 全局唯一的系统消息队列
  2. 线程内核对象中的线程消息队列

新的消息类型

鼠标按键消息类型



//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//  WM_RBUTTONDOWN - 按下右键
//  WM_LBUTTONDOWN - 按下左键
//  WM_RBUTTONUP - 弹起右键
//  WM_LBUTTONUP - 弹起左键
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择: 
            switch (wmId)
            {
            case IDM_ABOUT:
               
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_RBUTTONDOWN :
        MessageBox(hWnd, TEXT("按下右键"), NULL, MB_OK);
        break;
    case WM_LBUTTONDOWN:
        MessageBox(hWnd, TEXT("按下左键"), NULL, MB_OK);
        break;
    case WM_RBUTTONUP:
        MessageBox(hWnd, TEXT("弹起右键"), NULL, MB_OK);
        break;

    case WM_LBUTTONUP:
        MessageBox(hWnd, TEXT("弹起左键"), NULL, MB_OK);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

TranslateMessage API 翻译消息

WM_KEYDOWN 消息 -> 按键按下

https://msdn.microsoft.com/query/dev15.query?appId=Dev15IDEF1&l=ZH-CN&k=k(WINUSER%2FWM_KEYDOWN);k(WM_KEYDOWN);k(DevLang-C%2B%2B);k(TargetOS-Windows)&rd=true;k(WM_KEYDOWN);k(DevLang-C%2B%2B);k(TargetOS-Windows)&rd=true)


#include "stdafx.h"
#include "WindowsMessage.h"


LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    TCHAR className[] = TEXT("MyFirstWnd");
    //1 创建窗口类型模板
    WNDCLASS wndclass = { 0 };
    wndclass.lpszClassName = className; //名字 
    wndclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND; //背景画笔句柄
    wndclass.hInstance = hInstance; //窗口过程的实例句柄
    wndclass.lpfnWndProc = WndProc; //窗口过程函数

                                    //2 注册窗口
    RegisterClass(&wndclass);

    //3 创建窗口
    HWND hwindows = CreateWindow(className, TEXT("MYWINDOWS"), WS_OVERLAPPEDWINDOW, 500, 300, 300, 250, NULL, NULL, hInstance, NULL);

    //4 显示窗口
    ShowWindow(hwindows, SW_SHOW);

    //5 构建消息循环
    MSG msg = { NULL };
    while (GetMessage(&msg, NULL, NULL, NULL))
    {
        //调用消息转换 否则有的消息无法捕捉
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;

}



//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//  WM_RBUTTONDOWN - 按下右键
//  WM_LBUTTONDOWN - 按下左键
//  WM_RBUTTONUP - 弹起右键
//  WM_LBUTTONUP - 弹起左键
//
//  WM_KEYDOWN - 按键消息
//  WM_CHAR - 按键消息 直接判断anscii码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择: 
            switch (wmId)
            {
            case IDM_ABOUT:
               
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_KEYDOWN:
        //要想捕捉到此消息,必须在创建窗口时的第5步构建消息循环的时候 调用TranslateMessage
        //WM_KEYDOWN 的msdn文档中有强调
        if (wParam == 0x42)
        {
            MessageBox(hWnd, TEXT("b"), NULL, MB_OK);
        }
        break;
    case WM_CHAR:
        //此消息也需要 TranslateMessage
        if (wParam == 'a')
        {
            MessageBox(hWnd, TEXT("a"), NULL, MB_OK);
        }
        break;

    case WM_RBUTTONDOWN :
        //MessageBox(hWnd, TEXT("按下右键"), NULL, MB_OK);
        break;
    case WM_LBUTTONDOWN:
        //MessageBox(hWnd, TEXT("按下左键"), NULL, MB_OK);
        break;
    case WM_RBUTTONUP:
        MessageBox(hWnd, TEXT("弹起右键"), NULL, MB_OK);
        break;

    case WM_LBUTTONUP:
        MessageBox(hWnd, TEXT("弹起左键"), NULL, MB_OK);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

模拟消息api

LRESULT WINAPI SendMessage
(
    HWND hWnd.   //目标窗口句柄
    UINT Msg,    //要发送的消息
    WPARAM wParam, //消息内容
    LPARAM IParam  //消息内容
);
BOOL WINAPI PostMessage
(
    HWND hWnd.   //目标窗口句柄
    UINT Msg,    //要发送的消息
    WPARAM wParam, //消息内容
    LPARAM IParam  //消息内容
)

postMessage和sendMessage的区别

  • 返回时间不同

        `PostMessage`发送消息后就 `立即返回`
        `SendMessage`发送消息后,等待消息`处理函数处理完毕后才返回`
  • 发送的过程不同

    在同一个线程中:
        `PostMessage`发送消息时,消息要`先放入系统消息队列`总
        `SendMessage`发送消息时,由`User`模块调用目标窗口的处理函数处理消息,并将结果返回
        
    在不同的线程中:
        `PostThreadMessage`代替`PostMessage`指定消息发送给哪一个线程
        `SendMessage`发送消息到目标窗口所属的线程的消息队列中,然后发送消息的线程在`User`模块内监视和等待消息处理,直到目标窗口处理完返回
    
]]>
0 https://luodaoyi.com/p/message-mechanism-and-analog-message.html#comments https://luodaoyi.com/feed/p/message-mechanism-and-analog-message.html
新建一个窗口程序 https://luodaoyi.com/p/create-a-new-window-program.html https://luodaoyi.com/p/create-a-new-window-program.html Tue, 29 May 2018 01:10:08 +0800 luodaoyi 新建一个窗口程序

消息机制

创建窗口的几个步骤

  1. 创建窗口类
  2. 注册窗口类
  3. 创建窗口
  4. 显示窗口
  5. 构建消息循环

创建过程

demo : https://github.com/luodaoyi/cpp_code/tree/master/MemoryInjectTool/CreateWindows

//1 创建窗口类型模板
    WNDCLASS wndclass = { 0 };
    wndclass.lpszClassName = className; //名字 
    wndclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND; //背景画笔句柄
    wndclass.hInstance = hInstance; //窗口过程的实例句柄
    wndclass.lpfnWndProc = WndProc; //窗口过程函数

    //2 注册窗口
    RegisterClass(&wndclass);

    //3 创建窗口
    HWND hwindows = CreateWindow(className, TEXT("MYWINDOWS"), WS_OVERLAPPEDWINDOW, 500, 300, 300, 250, NULL, NULL, hInstance,NULL);
   

    //创建窗口

    HWND hsitc1 = CreateWindow(L"STATIC", TEXT("账号:"), WS_CHILD | WS_VISIBLE, 10, 30, 50, 20, hwindows, HMENU(IDC_STATIC1), hInstance, NULL);
    HWND hstic2 = CreateWindow(L"STATIC", TEXT("密码"), WS_CHILD | WS_VISIBLE, 10, 80, 50, 20, hwindows, HMENU(IDC_STATIC2), hInstance, NULL);
    HWND hedit1 = CreateWindow(L"EDIT", NULL, WS_CHILD | WS_VISIBLE, 80, 30, 100, 20, hwindows, HMENU(IDC_EDIT1), hInstance, NULL);
    HWND hedit2 = CreateWindow(L"EDIT", NULL, WS_CHILD | WS_VISIBLE, 80, 80, 100, 20, hwindows, HMENU(IDC_EDIT2), hInstance, NULL);
    HWND hbutt1 = CreateWindow(L"BUTTON", TEXT("登录"), WS_CHILD | WS_VISIBLE, 50, 120, 50, 25, hwindows, HMENU(IDC_BUTTM1), hInstance, NULL);
    HWND hbutt2 = CreateWindow(L"BUTTON", TEXT("取消"), WS_CHILD | WS_VISIBLE, 110, 120, 50, 25, hwindows, HMENU(IDC_BUTTM2), hInstance, NULL);

    //4 显示窗口
    ShowWindow(hwindows,SW_SHOW);

    //5 构建消息循环
    MSG msg = { NULL };
    while (GetMessage(&msg,NULL,NULL,NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
]]>
0 https://luodaoyi.com/p/create-a-new-window-program.html#comments https://luodaoyi.com/feed/p/create-a-new-window-program.html
office2016 visio2016 project2016零售版转换vol版bat https://luodaoyi.com/p/office2016-visio2016-project2016-retail-version-to-vol-version-bat.html https://luodaoyi.com/p/office2016-visio2016-project2016-retail-version-to-vol-version-bat.html Tue, 29 May 2018 00:53:24 +0800 luodaoyi http://msdn.itellyou.cn/网站上下载的是office2016是零售版的,转换为vol,将下列文本另存为bat文件,运行即可

@ECHO OFF&PUSHD %~DP0

setlocal EnableDelayedExpansion&color 3e & cd /d "%~dp0"
title office2016 retail转换vol版

%1 %2
mshta vbscript:createobject("shell.application").shellexecute("%~s0","goto :runas","","runas",1)(window.close)&goto :eof
:runas

if exist "%ProgramFiles%\Microsoft Office\Office16\ospp.vbs" cd /d "%ProgramFiles%\Microsoft Office\Office16"
if exist "%ProgramFiles(x86)%\Microsoft Office\Office16\ospp.vbs" cd /d "%ProgramFiles(x86)%\Microsoft Office\Office16"

:WH
cls
echo.
echo                         选择需要转化的office版本序号
echo.
echo --------------------------------------------------------------------------------                                                         
echo                 1. 零售版 Office Pro Plus 2016 转化为VOL版
echo.
echo                 2. 零售版 Office Visio Pro 2016 转化为VOL版
echo.
echo                 3. 零售版 Office Project Pro 2016 转化为VOL版
echo.
echo. --------------------------------------------------------------------------------
                                                        
set /p tsk="请输入需要转化的office版本序号【回车】确认(1-3): "
if not defined tsk goto:err
if %tsk%==1 goto:1
if %tsk%==2 goto:2
if %tsk%==3 goto:3

:err
goto:WH

:1
cls

echo 正在重置Office2016零售激活...
cscript ospp.vbs /rearm

echo 正在安装 KMS 许可证...
for /f %%x in ('dir /b ..\root\Licenses16\proplusvl_kms*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul

echo 正在安装 MAK 许可证...
for /f %%x in ('dir /b ..\root\Licenses16\proplusvl_mak*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul

echo 正在安装 KMS 密钥...
cscript ospp.vbs /inpkey:XQNVK-8JYDB-WJ9W3-YJ8YR-WFG99

goto :e

:2
cls

echo 正在重置Visio2016零售激活...
cscript ospp.vbs /rearm

echo 正在安装 KMS 许可证...
for /f %%x in ('dir /b ..\root\Licenses16\visio???vl_kms*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul

echo 正在安装 MAK 许可证...
for /f %%x in ('dir /b ..\root\Licenses16\visio???vl_mak*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul

echo 正在安装 KMS 密钥...
cscript ospp.vbs /inpkey:PD3PC-RHNGV-FXJ29-8JK7D-RJRJK

goto :e

:3
cls

echo 正在重置Project2016零售激活...
cscript ospp.vbs /rearm

echo 正在安装 KMS 许可证...
for /f %%x in ('dir /b ..\root\Licenses16\project???vl_kms*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul

echo 正在安装 MAK 许可证...
for /f %%x in ('dir /b ..\root\Licenses16\project???vl_mak*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul

echo 正在安装 KMS 密钥...
cscript ospp.vbs /inpkey:YG9NW-3K39V-2T3HJ-93F3Q-G83KT

goto :e

:e
echo.
echo 转化完成,按任意键退出!
pause >nul
exit
]]>
0 https://luodaoyi.com/p/office2016-visio2016-project2016-retail-version-to-vol-version-bat.html#comments https://luodaoyi.com/feed/p/office2016-visio2016-project2016-retail-version-to-vol-version-bat.html
模块隐藏 https://luodaoyi.com/p/module-concealment.html https://luodaoyi.com/p/module-concealment.html Thu, 24 May 2018 01:02:11 +0800 luodaoyi 模块隐藏

遍历模块

HANDLE WINAPI CreateToolhelp32Snapshot(
    DWORD dwFlags,
    DWORD th32ProcessID
)

//dwFlags:
TH32CS_SNAPMODULE   遍历模块

PEB

(Process Environment Block 进程环境块)
存放进程信息,每个进程都有自己的PEB信息

如何找到PEB

  1. EPROCESS进程内核对象结构体中 0x1b0偏移的位置
  2. TEB线程环境块的 0x30位置

(实际上32位程序中的PEB的位置是固定的)

TEB

(Thread EnvironmentBlock 线程环境块)
系统在此TEB种保存频繁使用的线程相关的数据

如何找到TEB:
段寄存器fs中记录了TEB的存储位置

TEB偏移0X30的位置记录了TEB的地址

可以通过以下汇编来获取

MOV EAX,FS:[0x30]
 
//获得PEB
PEB_LDR_DATA* pPebLdrData=NULL;
_asm
{
    mov eax,fs:[0x30]
    mov ecx,[eax+0x0c]
    mov pPebLdrData,ecx
}
//获得LDR_DATA

pPebLdrData = (PEB_LDR_DATA*)*(_NT_PEB + 0x0c)

]]>
0 https://luodaoyi.com/p/module-concealment.html#comments https://luodaoyi.com/feed/p/module-concealment.html
文件系统 https://luodaoyi.com/p/file-system-1.html https://luodaoyi.com/p/file-system-1.html Tue, 22 May 2018 21:53:57 +0800 luodaoyi 文件系统

什么是文件系统

文件系统是操作系统用于管理磁盘上文件的方法和数据结构,简单说就是在磁盘上如何组织文件的方法,是软件层面的东西

windows上有哪几种文件系统

类型NTFSFAT32
磁盘分区容量2T512MB - 2TB (早先只有32GB)
单个文件容量4GB以上最大4GB
EFS加密YN
磁盘配额YN

如何操作文件系统

  • 卷相关的API
API功能
GetLogicalDrives( )获取卷
GetLogicalDriveString()获取所有卷盘符字符串
GetDriveType()获取卷的类型
GetVolumeInformation ()获取卷的信息
  • 目录相关的API
API功能
CreateDirectory()创建目录(文件夹)
RemoveDirectory()删除目录(文件夹)
MoveFile()移动文件(修改目录名称)
GetCurrentDirectory()获取当前进程的目录
SetCurrentDirectory()设置应用程序的当前目录
  • 文件操作相关
API功能
CreateFile()创建/打开文件
CloseHandle()关闭文件
GetFileSize()获取文件大小
GetFileAttributes()获取文件相关信息
ReadFile() / WriteFile() / CopyFile() / DeleteFile()读写拷贝删除文件
FindFirstFile() / FindNextFile()查找文件
]]>
0 https://luodaoyi.com/p/file-system-1.html#comments https://luodaoyi.com/feed/p/file-system-1.html
远程线程注入 https://luodaoyi.com/p/remote-thread-injection-1.html https://luodaoyi.com/p/remote-thread-injection-1.html Tue, 22 May 2018 21:53:12 +0800 luodaoyi 远程线程注入

线程是什么

如果说进程是个大房子,那么线程是进程中干活的人

线程是进程的灵魂
使用进程提供的数据 执行进程提供的代码
临时数据存储在计算机的寄存器中

创建线程

//在自己的进程中创建线程
CreateThread()
//在别人的进程中创建线程
HANDLE WINAPI CreateRemoteThread
(
     _In_     HANDLE hProcess,    //目标进程句柄
      _In_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
      _In_     SIZE_T dwStackSize,    //目标线程栈大小
      _In_     LPTHREAD_START_ROUTINE lpStartAddress,//目标线程地址
      _In_     LPVOID lpParameter,    //目标线程参数
     _In_     DWORD dwCreationFlags,//创建标志位
     _Out_  LPDWORD lpThreadId    //返回被创建线程的ID
);

远程线程注入的关键点

  1. 通过CreateRemoteThread创建线程
  2. 被创建的线程的本体在目标进程内部
  3. 被创建的线程使用的各类资源均依赖于目标进程

思考:

如果利用之前学习过的知识将我们想要实现的代码加入到目标进程中去?

远程线程的几个关键点

  1. 被创建的线程在别的进程中执行
  2. 呗创建的线程锁依赖的代码或数据都来自于目标进程

如果想要在目标进程中干我们想干的事,我们就需要吧自己的功能代码加入到目标进程内部,这个也就是常说的代码注入

我们目前学过的知识就可以实现一些注入的功能

  1. 内存的操作
  2. 动态链接库

通过直接读写内存的方式

  1. 利用VirtualAllocEx在目标进程中申请一段内存空间
  2. 通过WriteProcessMemory在目标进程中刚申请的空间内将我们的功能代码的硬编码写入
  3. CreateRemoteThread 启动我们的目标代码

优点: 操作简单不易呗发现
缺点: 因为远程线程锁执行的代码和利用的资源只能是目标进程提供的,那么我们写入的这段硬编码必须得脱离其他依赖独立运行,只能直接调用API,不能使用静态库提供的函数,不能直接使用动态库使用的函数,不能出现随意的调用或者jmp,在构造这种代码的时候会非常复杂,当然按照以上要求构造出来的代码我们还有一种叫法,叫做ShellCode

DllMain

BOOL WINAPI DllMain
(
        HINSTANCE hinstDLL;//DLL模块举办(DLL 被加载的位置)
        DWORD fwdReason, //  制定本地DLLMain被调用的原因
        LPVOID ipvReserved; //保留位
)

//fdwReason的一些宏说明:

DLL_PROCESS_ATTACH:
      当进程第一次将该DLL映射到内存空间时,我们的进程就会调用一次这个DllMain并传入这个参数
DLL_PROCESS_DETACH:
      当进程将当前DLL从内存空间解除映射的时候,就会调用一次DllMain并传入这个参数
DLL_THREAD_ATTCH:
      每当有一个新的线程创建,都会调用一次DllMain并传入这个参数
DLL_THREAD_DEACH:
      每当有一个线程结束(ExitThread)时就会调用一次DllMain并传入这个参数,如果线程是因为TerminateThread函数而结束的则不会调用

通过动态链接库的方式

  1. 利用一些手段加载带有我们功能函数的DLL
  2. 通过DLLMAIN来启动我们的功能

优点:操作简单实现也简单,写在DLL中的功能函数不需要想 ShellCode那样做到什么也不依赖,因为DLL被加载后重定位会替我们搞定这些麻烦事,所以在DLL中可以像写我们普通的正常程序一样来写我们的功能代码
缺点:容易被检测

加载DLL:

]]>
0 https://luodaoyi.com/p/remote-thread-injection-1.html#comments https://luodaoyi.com/feed/p/remote-thread-injection-1.html
动态链接库 https://luodaoyi.com/p/dynamic-link-library.html https://luodaoyi.com/p/dynamic-link-library.html Tue, 22 May 2018 21:51:05 +0800 luodaoyi 动态链接库

静态链接库的缺陷

  • 链接时将函数加入到exe导致exe变大
  • 在运行时对于不同进程他们所使用的同一个函数都会独占空间,造成资源浪费

怎么解决

 利用之前学习过的内存知识,例如映射类型的内存块
 将这些公共代码放在文件中没在进程运行的时候在加载该文件
 并且在内存中只需要加载一边,不同进程使用同一份公共代码时,只需要将之前加载过的这个文件映射到自己内存中即可

什么是动态链接库

动态链接库(dynamic link library 缩写位 dll),是微软公司在windows操作系统中
实现共享函数库概念的一种方式

这些库函数的扩展是 .dll .ocx(包含activeX控制的库)

创建动态链接库

  1. extern "C" _declspec(dllexport) 返回类型 调用约定 函数名 (参数列表)
  2. 使用.def文件
    制定导出函数,并告知编译器不要以修饰后的函数名作为导出函数名,而以指定的函数名导出函数
EXPORTS
函数名   @编号
函数名   @编号    NONAME

使用序号导出的好处:

名字是一段程序最精华的注释,通过名字可以直接猜到函数的功能

通过使用序号,可以达到隐藏的目的

如何调用动态链接库(显式调用)

  1. 定义函数指针
  2. 声明函数变量
  3. 通过LoadLibrary() 动态加载DLL到内存中
  4. 通过GetProcAddress()获取函数地址
  5. 调用函数
  6. FreeLibrary()释放动态链接库

exp:

// 定义
// MyFunction.h
//根据名字查找进程id
//extern "C" _declspec(dllexport) 返回类型 调用约定 函数名 (参数列表)
extern "C" _declspec(dllexport) DWORD _stdcall find_processid_by_name(PWCHAR process_name);

// MyFunction.cpp
#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>

DWORD find_processid_by_name(PWCHAR process_name)
{

    HANDLE hand = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if ((int)hand == -1)
    {
        return GetLastError();
    }
    PROCESSENTRY32 process_info = { 0 };
    process_info.dwSize = sizeof PROCESSENTRY32;

    if (!Process32First(hand, &process_info))
    {
        return GetLastError();
    }

    do
    {
        if (!wcscmp(process_info.szExeFile, process_name))
        {
            return process_info.th32ProcessID;
        }

    } while (Process32Next(hand,&process_info));
    return 0;
}


//调用
//Main.cpp
#include "stdafx.h"
#include "windows.h"

//显示的导入

//1 定义函数指针
typedef DWORD(_cdecl * PFindProcessW)(PWCHAR);
//2 定义变量
PFindProcessW pMyFindProcessW = NULL;


int main()
{
    //3 装载DLL
    HMODULE hModule = LoadLibrary(L"动态链接库.dll");

    //4 获得函数

    pMyFindProcessW = (PFindProcessW)GetProcAddress(hModule, "find_processid_by_name");
    DWORD err = GetLastError();

    WCHAR name[] = L"notepad.exe";
    printf_s("PID=%d \r\n", pMyFindProcessW(name));
    getchar();
    return 0;
}

DLL和EXE的区别

  • 动态链接库DLL与可执行文件exe本质上没有区别,我们统称为模块
  • 他们内部的数据组织结构都遵循一个叫做PE文件格式的格式
  • 两者都可以对外提供函数,只不过DLL提供的更多
]]>
0 https://luodaoyi.com/p/dynamic-link-library.html#comments https://luodaoyi.com/feed/p/dynamic-link-library.html
静态链接库 https://luodaoyi.com/p/static-link-library.html https://luodaoyi.com/p/static-link-library.html Tue, 22 May 2018 21:49:41 +0800 luodaoyi 静态链接库

如何创建静态链接库

  • vs新建项目,选择静态链接库
  • 在项目文件中新建 .cpp 文件与.h 文件

项目编译生成后会产生一个 .lib文件

如何使用静态链接库

将生成的.h与.lib文件复制到项目根目录

  • 直接添加.lib与.h到项目中
  • 在项目代码中添加头文件引用
#include "xxx.h"

#pragma comment(lib,"xxx.lib")

静态链接库的生成

lib的生成和我们的exe是一样的,也是要经过预处理编译会变的过程,最终生成的lib 就是多个.o(obj)文件的集合体

编译过程

  • 预处理
  • 编译
  • 会变
  • 链接

连接的过程就相当于将多个.o文件拼接在一起形成exe文件,而对于lib便是将Lib中需要的东西抽取出来和其他.o拼接在一起

]]>
0 https://luodaoyi.com/p/static-link-library.html#comments https://luodaoyi.com/feed/p/static-link-library.html