《Windows PE》5.1 导出表

news2025/1/18 3:25:40

导出表(Export Table)是一个在可执行文件或动态链接库(DLL)中的数据结构,用于描述该文件中导出的函数、变量和其他符号。导出表通常位于DLL动态链接库中。

本节必须掌握的知识点:

        导入表数据结构

        PE中的导入表

        IAT函数地址表

        手工重构导入表

5.1.1 导出表数据结构

导出表由以下三个主要部分组成:

●导出地址表(Export Address Table,EAT):导出地址表是一个指向导出函数地址的指针数组。每个导出函数在导出地址表中有一个对应的指针。在运行时,当其他模块调用这个DLL中的导出函数时,将使用该表中的指针来定位和调用函数。

●导出名称表(Export Name Table,ENT):导出名称表是一个字符串数组,包含了所有导出函数的名称。每个导出函数名称在导出名称表中都有一个对应的字符串。导出地址表中的指针与导出名称表中的字符串是一一对应的。

●导出函数序号表(Export Function Ordinal Table)是PE文件中导出表的一部分,用于映射导出函数的序号和地址。导出函数序号表是一个由WORD类型的数组组成,每个元素对应一个导出函数。序号表的长度等于导出函数的数量。

导出表的结构和内容由编译器和链接器在构建可执行文件或DLL时生成。导出表允许其他模块(可执行文件、DLL或其他)通过导入表来引用和调用这些导出的函数和符号。

在Windows平台上,您可以使用一些工具来查看PE文件的导出表,例如Dependency Walker、dumpbin工具或PE浏览器等。

 注意

导出表只包含被明确定义为导出的符号。如果某个符号未被明确导出,它将不会出现在导出表中。您可以使用关键字 __declspec(dllexport) 或者通过.def文件来指定哪些符号应该被导出。

导出表数据结构

导入表描述符IMAGE_IMPORT_DESCRIPTOR的个数与调用的动态链接库个数相等,而导出表描述符IMAGE_EXPORT_DIRECTORY的个数只有一个。

typedef struct _IMAGE_EXPORT_DIRECTORY {

    DWORD   Characteristics;               // 导出表的特征标志

    DWORD   TimeDateStamp;              // 时间戳

    WORD    MajorVersion;               // 主版本号

    WORD    MinorVersion;               // 次版本号

    DWORD   Name;                       // 模块名称的RVA

    DWORD   Base;                     // 导出函数序号的基准值

    DWORD   NumberOfFunctions;          // 导出函数的数量

    DWORD   NumberOfNames;             // 导出函数名称的数量

    DWORD   AddressOfFunctions;         // 导出函数地址表的RVA

    DWORD   AddressOfNames;              // 导出函数名称表的RVA

    DWORD   AddressOfNameOrdinals;      // 导出函数序号表的RVA

} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

这个结构用于描述PE文件中的导出表。下面是对各个成员的注释:

Characteristics:导出表的特征标志,例如是否按序号导出。

TimeDateStamp:导出表的时间戳,表示导出表生成的时间。

MajorVersion 和 MinorVersion:导出表的版本号,用于指示导出表的版本信息。

Name:指向导出模块名称的指针(RVA)。

Base:导出函数的序号基准值。导出函数编号的起始值。DLL中的第一个导出函数并不是从0开始的,某导出函数的编号等于从AddressOfFunctions开始的顺序号加上这个值。

NumberOfFunctions:导出函数的数量。

NumberOfNames:导出函数名称的数量。

AddressOfFunctions:导出函数地址表的指针(RVA),包含导出函数的地址。该指针指向了全部导出函数的入口地址的起始。从入口地址开始为双字数组,数组的个数由字段IMAGE_EXPORT_DIRECTORY.NumberOfFimctions决定。导出函数的每一个地址按函数的编号顺序依次往后排开。在内存中,我们可以通过函数编号来定位某个函数的地址。

AddressOfNames:导出函数名称表的指针(RVA),包含导出函数的名称。该指针指向的位置是一连串的双字值,这些双字值均指向了对应的定义了函数名的函数的字符串地址。这一连串的双字个数为 NumberOfNames。

AddressOfNameOrdinals:导出函数序号表的指针(RVA),用于匹配导出函数的名称和地址。该值也是一个指针,与AddressOfNames是一一对应关系,所不同的是,AddressOfNames指向的是字符串的指针数组,而AddressOfNameOrdinals则指向了该函数在AddressOfFunctions中的索引值。

 注意

索引值是一个字,而非双字。该值与函数编号是两个不同的概念,两者之间的关系为:

索引值=编号 - nBase

导入表描述各个字段之间的关系可以用下图来描述:

                                         图5-1 PE导出表结构

5.1.2 定位导出表

导出表位于PE文件的数据目录第0项中,位于导入表之前。接下来我们通过一个实例具体分析导出表的结构。

首先我们要写一个包含导出表的DLL动态链接库,然后再写一个EXE执行文件调用导出函数。

实验三十三:延迟加载版本2示例

       以下是一个使用延迟加载版本2的C语言示例代码:

       ●源代码:

winResult.h

/*

; winResult.dll 导出函数:

; 1、AnimateOpen(DWORD)

;   窗口抖动进入效果

; 2、AnimateClose(DWORD)

;   窗口抖动退出效果

; 3、FadeInOpen(DWORD)

;   窗口淡入效果,仅运行在2000/XP以上操作系统

; 4、FadeOutClose(DWORD)

;   窗口淡出效果,仅运行在2000/XP以上操作系统

; ******************************************************************** /

*/

#pragma once

#include <windows.h>

#ifdef _cplusplus //如果C++模式编译

    #ifdef API_EXPORT

        #define EXPORT   extern "C" __declspec(dllexport)  

    #else

        #define EXPORT    extern "C" __declspec(dllimport

    #endif

#else

    #ifdef API_EXPORT

        #define EXPORT   __declspec(dllexport

    #else

        #define EXPORT   __declspec(dllimport

    #endif

#endif

EXPORT  void AnimateOpen(HWND);

EXPORT  void AnimateClose(HWND);

EXPORT  void FadeInOpen(HWND);

EXPORT  void FadeOutClose(HWND);

winResult.c

/*------------------------------------------------------------------------

 FileName:winResult.c

 实验33:一个简单的动态链接库例子

 (c) bcdaren, 2024

-----------------------------------------------------------------------*/

#include <windows.h>

#define API_EXPORT

#include "winResult.h"

#define MAX_XYSTEPS     50

#define DELAY_VALUE     50  //动画效果使用的步长

#define X_STEP_SIZE     10

#define Y_STEP_SIZE     9

#define X_START_SIZE    20

#define Y_START_SIZE    10

#define LMA_ALPHA       2

#define LMA_COLORKEY    1

//入口和退出点

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)

{

    return TRUE;

}

//私有函数:本函数在dll内部使用

DWORD TopXY(DWORD wDim,DWORD sDim)

{

    return (sDim / 2 - wDim / 2);

}

//窗口抖动进入效果

EXPORT  void AnimateOpen(HWND hWin)

{

    RECT rect;

    DWORD Xsize, Ysize,Xplace,Yplace;

    int sWth,sHth,counts;

    GetWindowRect(hWin, &rect);

    Xsize = X_START_SIZE;

    Ysize = Y_START_SIZE;

    sWth = GetSystemMetrics(SM_CXSCREEN);

    Xplace = TopXY(Xsize, sWth);

    sHth = GetSystemMetrics(SM_CYSCREEN);

    Yplace = TopXY(Ysize, sHth);

    counts = MAX_XYSTEPS;

    while (counts--)

    {

        MoveWindow(hWin, Xplace, Yplace, Xsize, Ysize, FALSE);

        ShowWindow(hWin, SW_SHOWNA);

        Sleep(DELAY_VALUE);

        ShowWindow(hWin, SW_HIDE);

        Xsize += X_STEP_SIZE;

        Ysize += Y_STEP_SIZE;

        Xplace = TopXY(Xsize, sWth);

        Yplace = TopXY(Ysize, sHth);

    }

    Xsize = rect.right - rect.left;

    Ysize = rect.bottom - rect.top;

    Xplace = TopXY(Xsize,sWth);

    Yplace = TopXY(Ysize,sHth);

    MoveWindow(hWin,Xplace,Yplace,Xsize,Ysize,TRUE);

    ShowWindow(hWin, SW_SHOW);

}

//窗口抖动退出效果

EXPORT void AnimateClose(HWND hWin)

{

    RECT rect;

    DWORD Xsize, Ysize, Xplace, Yplace;

    int sWth, sHth, counts;

    ShowWindow(hWin, SW_HIDE);

    GetWindowRect(hWin, &rect);

    Xsize = rect.right - rect.left;

    Ysize = rect.bottom - rect.top;

    sWth = GetSystemMetrics(SM_CXSCREEN);

    Xplace = TopXY(Xsize, sWth);

    sHth = GetSystemMetrics(SM_CYSCREEN);

    Yplace = TopXY(Ysize, sHth);

    counts = MAX_XYSTEPS;

    while (counts--)

    {

        MoveWindow(hWin, Xplace, Yplace, Xsize, Ysize, FALSE);

        ShowWindow(hWin, SW_SHOWNA);

        Sleep(DELAY_VALUE);

        ShowWindow(hWin, SW_HIDE);

        Xsize -= X_STEP_SIZE;

        Ysize -= Y_STEP_SIZE;

        Xplace = TopXY(Xsize, sWth);

        Yplace = TopXY(Ysize, sHth);

    }

}

//窗口淡入效果,仅运行在2000/XP以上操作系统

EXPORT void FadeInOpen(HWND hWin)

{

    const TCHAR User32[] = TEXT("user32.dll");

    const CHAR SLWA[] = "SetLayeredWindowAttributes";//函数名使用ASCII码字符

    FARPROC pSLWA;

    int Value = 90;

    LONG stl = GetWindowLong(hWin, GWL_EXSTYLE);//检索扩展的窗口样式

    // 增加“分层窗口”样式

    stl |= WS_EX_LAYERED;  

    SetWindowLong(hWin,GWL_EXSTYLE,stl);

    //获取SetLayeredWindowAttributes在user32.dll中的地址

    pSLWA = GetProcAddress(GetModuleHandle(User32), (LPCSTR)SLWA);

    //设置分层窗口的不透明度和透明度颜色键

    pSLWA(hWin,0,0,LMA_ALPHA);

    ShowWindow(hWin, SW_SHOWNA);

    while (Value != 255)

    {

        pSLWA(hWin,Value,Value,LMA_COLORKEY + LMA_ALPHA);

        Sleep(DELAY_VALUE);

        Value += 15;

    }

    pSLWA(hWin,0,255,LMA_ALPHA);

}

//窗口淡出效果,仅运行在2000/XP以上操作系统

EXPORT void FadeOutClose(HWND hWin)

{

    const TCHAR User32[] = TEXT("user32.dll");

    const CHAR SLWA[] = "SetLayeredWindowAttributes";

    FARPROC pSLWA;

    int Value = 255;

    LONG stl = GetWindowLong(hWin, GWL_EXSTYLE);//检索扩展的窗口样式

    // 增加“分层窗口”样式

    stl |= WS_EX_LAYERED;

    SetWindowLong(hWin, GWL_EXSTYLE, stl);

    //获取SetLayeredWindowAttributes在user32.dll中的地址

    pSLWA = GetProcAddress(GetModuleHandle(User32), (LPCSTR)SLWA);

    //设置分层窗口的不透明度和透明度颜色键

    pSLWA(hWin, 0,255, LMA_ALPHA);

    while (Value != 0)

    {

        pSLWA(hWin, Value, Value, LMA_COLORKEY + LMA_ALPHA);

        Sleep(DELAY_VALUE);

        Value -= 15;

    }

}

FirstWindow.c

/*------------------------------------------------------------------------

 FileName:FirstWindow.c

 实验33:执行文件

 ;功能:简单窗口程序

;具有窗口的大部分基本特性,其中显示和退出使用了渐入和渐出效果

;该程序主要演示自己制作的dll的函数调用

 (c) bcdaren, 2024

-----------------------------------------------------------------------*/

#include <windows.h>

#include "resource.h"

#include "winResult.h"

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

HWND hWinMain; //窗口句柄

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

    LPSTR lpCmdLine, int nShowCmd)//默认填写

{

    const TCHAR szClassName[] = TEXT("MyClass");

    const TCHAR szCaptionMain[] = TEXT("窗口特效演示");

    MSG msg;      //MSG 结构变量

    WNDCLASSEX wndclass; //WNDCLASSEX结构变量

    wndclass.style = CS_HREDRAW | CS_VREDRAW;//重叠窗口

    wndclass.lpfnWndProc = WndProc;//回调函数指针

    wndclass.cbClsExtra = 0;

    wndclass.cbWndExtra = 0;

    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//窗口背景色

    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

    wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));

    wndclass.lpszMenuName = NULL;//菜单

    wndclass.hInstance = hInstance;//实例句柄

    wndclass.cbSize = sizeof(WNDCLASSEX);

    wndclass.hIconSm = NULL;

    wndclass.lpszClassName = szClassName;

    if (!RegisterClassEx(&wndclass))

    {

        MessageBox(0, TEXT("This program requires Windows NT!"),

            szClassName, MB_ICONERROR);

        return 0;

    }

    hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,

        szClassName,//窗口类名

        szCaptionMain,//窗口标题

        WS_OVERLAPPEDWINDOW,     //窗口样式

        GetSystemMetrics(SM_CXSCREEN) / 4,

        GetSystemMetrics(SM_CYSCREEN) / 4,

        GetSystemMetrics(SM_CXSCREEN) / 2,

        GetSystemMetrics(SM_CYSCREEN) / 2,

        NULL, // 父窗口句柄

        NULL, // 窗口菜单句柄

        hInstance, // 程序实例句柄

        NULL); // 创建参数

    //ShowWindow(hWinMain, nShowCmd); //显示窗口

    FadeInOpen(hWinMain);//外部链接库函数

    UpdateWindow(hWinMain);

    while (GetMessage(&msg, NULL, 0, 0))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)

{

    HDC hdc;

    PAINTSTRUCT ps;

    RECT rect;

    const TCHAR szText[] = TEXT("Welocome to 编程达人!");

    switch (message)

    {

    case WM_PAINT:

        hdc = BeginPaint(hwnd, &ps);

        GetClientRect(hwnd,&rect);

        DrawText(hdc,szText,-1,&rect,DT_SINGLELINE | DT_CENTER |DT_VCENTER);

        EndPaint(hwnd, &ps);

        return 0;

    case WM_CLOSE:

        FadeOutClose(hwnd);//外部链接库函数

        DestroyWindow(hwnd);

        return 0;

    case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

    }

    return DefWindowProc(hwnd, message, wparam, lparam);

}

运行

图5-2 FirstWindow窗口程序

       ●winResult.dll中导出表的定位:

    数据目录项:

00000170   10 25 00 00 90 00 00 00  A0 25 00 00 64 00 00 00   .%......?..d...

00000180   00 40 00 00 F8 00 00 00  00 00 00 00 00 00 00 00   .@..?..........

00000190   00 00 00 00 00 00 00 00  00 50 00 00 7C 01 00 00   .........P..|...

000001A0   F0 20 00 00 70 00 00 00  00 00 00 00 00 00 00 00   ?..p...........

000001B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

000001C0   60 21 00 00 40 00 00 00  00 00 00 00 00 00 00 00   `!..@...........

000001D0   00 20 00 00 8C 00 00 00  00 00 00 00 00 00 00 00   . ..?..........

000001E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

   

●导出表位于数据目录项的第0项。导出表RVA为00002510H,大小为90H。

节表:

000001F0   2E 74 65 78 74 00 00 00  A4 0F 00 00 00 10 00 00   .text...?......

00000200   00 10 00 00 00 04 00 00  00 00 00 00 00 00 00 00   ................

00000210   00 00 00 00 20 00 00 60  2E 72 64 61 74 61 00 00   .... ..`.rdata..

00000220   62 09 00 00 00 20 00 00  00 0A 00 00 00 14 00 00   b.... ..........

00000230   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 40   ............@..@

00000240   2E 64 61 74 61 00 00 00  8C 03 00 00 00 30 00 00   .data...?...0..

00000250   00 02 00 00 00 1E 00 00  00 00 00 00 00 00 00 00   ................

00000260   00 00 00 00 40 00 00 C0  2E 72 73 72 63 00 00 00   ....@..?rsrc...

00000270   F8 00 00 00 00 40 00 00  00 02 00 00 00 20 00 00   ?...@....... ..

00000280   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 40   ............@..@

00000290   2E 72 65 6C 6F 63 00 00  7C 01 00 00 00 50 00 00   .reloc..|....P..

000002A0   00 02 00 00 00 22 00 00  00 00 00 00 00 00 00 00   ....."..........

000002B0   00 00 00 00 40 00 00 42  00 00 00 00 00 00 00 00   ....@..B........

    ●导出表位于.rdata节区,FOA地址为:2510H-2000H+1400H=1910H。

    导出表描述符:

00001910   00 00 00 00 FF FF FF FF  00 00 00 00 60 25 00 00   ........`%..

00001920   01 00 00 00 04 00 00 00  04 00 00 00 38 25 00 00   ............8%..

00001930   48 25 00 00 58 25 00 00  F0 10 00 00 10 10 00 00   H%..X%..?......

00001940   C0 11 00 00 A0 12 00 00  6E 25 00 00 7B 25 00 00   ?..?..n%..{%..

00001950   87 25 00 00 92 25 00 00  00 00 01 00 02 00 03 00   ?..?..........

00001960   77 69 6E 52 65 73 75 6C  74 2E 64 6C 6C 00 41 6E   winResult.dll.An

00001970   69 6D 61 74 65 43 6C 6F  73 65 00 41 6E 69 6D 61   imateClose.Anima

00001980   74 65 4F 70 65 6E 00 46  61 64 65 49 6E 4F 70 65   teOpen.FadeInOpe

00001990   6E 00 46 61 64 65 4F 75  74 43 6C 6F 73 65 00 00   n.FadeOutClose..

typedef struct _IMAGE_EXPORT_DIRECTORY {

    DWORD   Characteristics;               // 00 00 00 00

    DWORD   TimeDateStamp;              // FF FF FF FF

    WORD    MajorVersion;               // 00 00

    WORD    MinorVersion;               // 00 00

    DWORD   Name;                       // 模块名称的RVA:00002560H

    DWORD   Base;                     // 导出函数序号的基准值:01

    DWORD   NumberOfFunctions;          // 导出函数的数量:04

    DWORD   NumberOfNames;             // 导出函数名称的数量:04

    DWORD   AddressOfFunctions;         // 导出函数地址表的RVA:00002538H

    DWORD   AddressOfNames;              // 导出函数名称表的RVA:00002548H

    DWORD   AddressOfNameOrdinals;      // 导出函数序号表的RVA:00002558H

} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

●导出函数地址表的RVA:00002538H对应的FOA地址为00001938。

F0 10 00 00 10 10 00 00 C0 11 00 00 A0 12 00 00

●导出函数名称表的RVA:00002548H对应的FOA地址为00001948。

6E 25 00 00 7B 25 00 00 87 25 00 00 92 25 00 00

0000196E:AnimateClose

0000197B:AnimateOpen

00001987:FadeInOpen

00001992:FadeOutClose

●导出函数序号表的RVA:00002558H对应的FOA地址为00001958。

00 00 01 00 02 00 03 00

●导出函数地址验证

第一步:将FirstWindow.exe拖入OD调试器,找到FadwInOpen函数的调用,F2下断点,如图5-3所示:

图5-3 FadwInOpen函数的调用

第二步:按下F7单步步入,进入FadwInOpen函数,入口地址为0x579511C0,如图5-4所示:

图5-4 FadwInOpen函数的入口

       第三步:打开内存映射窗口,找到winResult.dll模块,模块基址为0x57950000,如图5-5所示:

图5-5winResult.dll模块

FadwInOpen函数入口地址0x579511C0 = 0x57950000(基址)+0x 000011C0(RVA)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2198657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云计算:MySQL

第一周第一天-MySQL的SQL语句解析 数据库的介绍 什么是数据库 数据库是存储和管理数据的系统或集合&#xff0c;通常用于支持软件系统的高效数据处理和查询。它能够以结构化的方式组织数据&#xff0c;使用户可以快速存储、更新、查询和删除数据。数据库不仅保存数据&#xff0…

网络知识_001_浏览器输入域名

文章目录 网络模型IP地址&#xff0c;子网掩码&#xff0c;网关&#xff0c;网络地址&#xff0c;广播地址&#xff0c;NAT转换浏览器输入域名到网页打开发生了什么DNS获取顺序 网络模型 模型协议工具报文添加信息作用应用层http&#xff0c;https&#xff0c;ftp&#xff0c;…

Apache Flume 启动报错及解决方法

在使用 Apache Flume 时&#xff0c;可能会遇到启动报错的情况&#xff0c;其中一个常见问题就是 log4j 错误。本文将结合三个实际案例来分析这个问题&#xff0c;并提供相应的解决方法。 一、问题现象 案例一 执行命令 flume-ng agent -n a1 -c ../conf/ -f ./flume_info.conf…

Matlab绘图总结(进阶)

本文在前文的基础上进一步整理画图方法 MATLAB画动图_CSDN博客 1. 基础图形绘制 1.1 rectangle&#xff08;矩形&#xff0c;圆形&#xff09; 在前文中&#xff0c;讲解了如何使用rectangle&#xff0c;rectangle本意是用来画矩形的&#xff0c;其中&#xff0c;Curvature可…

MATLAB - 机器人机械臂设计轨迹规划器

系列文章目录 前言 本示例介绍了一种设计抓取和轨迹规划器的方法&#xff0c;该规划器可用于垃圾箱拣选系统。 在机器人技术中&#xff0c;垃圾箱拣选包括使用机械手从垃圾箱中取出物品。智能垃圾箱拣选是这一过程的高级版本&#xff0c;具有更强的自主性。使用摄像系统感知部件…

基于sklearn的机器学习应用平台 v2.0

基于sklearn的机器学习应用平台 v2.0 链接&#xff1a;https://pan.baidu.com/s/1nvHMTrtBmtPLT4oNXdw74A 提取码私信博主获取 关于作者 作者&#xff1a;小白熊 作者简介&#xff1a;精通python、matlab、c#语言&#xff0c;擅长机器学习&#xff0c;深度学习&#xff0c;机…

数据结构-4.6.KMP算法(旧版下)-朴素模式匹配算法的优化

一.绪论&#xff1a; 当主串字符和模式串字符不匹配时会执行jnext[j]来改变模式串的指针&#xff0c;但主串的指针不变。 二.求模式串的next数组&#xff1a; 1.例一&#xff1a; 如模式串abcabd&#xff0c;当第六个字符d匹配失败时&#xff0c;此时主串中前五个字符abcab都…

Golang | Leetcode Golang题解之第462题最小操作次数使数组元素相等II

题目&#xff1a; 题解&#xff1a; func partition(a []int, l, r int) int {x : a[r]i : l - 1for j : l; j < r; j {if a[j] < x {ia[i], a[j] a[j], a[i]}}a[i1], a[r] a[r], a[i1]return i 1 }func randomPartition(a []int, l, r int) int {i : rand.Intn(r-l1…

【学习笔记】零基础入门汇编语言(ARM架构+汇编的实际应用)

目录 一.汇编的前世今生 二.寄存器 三.ARM指令集 1.指令格式 2.寻址方式 3.伪指令 4.基本指令 4.1数据传输指令 4.2存储器访问指令 4.3压栈和出栈指令 4.4跳转指令 4.5算术运算指令 4.6逻辑运算指令 四.C语言与汇编混合编程 1.混合编程前置条件 2.混合编程优势 3.…

五款专业三维数据处理工具:GISBox、Cesiumlab、OSGBLab、灵易智模、倾斜伴侣深度解析

随着三维数据处理技术的广泛应用&#xff0c;尤其是在城市规划、地理信息系统&#xff08;GIS&#xff09;、工程监测等领域&#xff0c;处理倾斜摄影、三维建模以及大规模数据管理的需求日益增加。以下是五款我精心挑选的倾斜摄影和三维数据处理工具——GISBox、Cesiumlab、OS…

和鲸科技创始人范向伟:拐点即将来临,AI产业当前的三个瓶颈

在科技迅猛发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;无疑已经成为引领新一轮产业革命的核心动力之一。全球企业纷纷拥抱AI技术&#xff0c;试图借助其变革力量在竞争中突围&#xff0c;然而业界对AI产业化的拐点何时来临却众说纷纭。毕竟AI技术从实验室到商业…

三 星 SCX-4521F 硒 鼓 清 零 及 一 般 故 障 维 修 浅 谈

基本参数 耗材容量:SCX-4521D3/XIL(3000页) 功 率:平均功率350W、休眠模式10W 一般故障讲解 一、三星SCX-4521F打印机更换硒鼓(或加粉)后仍显示墨粉用尽 (加粉清零、关闭碳粉通知) 按菜单------#1934(快速按完)------屏幕会有TECH字母显示------菜单------向…

PCB缺陷检测数据集 xml 可转yolo格式 ,共10688张图片

PCB缺陷检测数据集&#xff08;yolov5,v7,v8&#xff09; 数据集总共有两个文件夹&#xff0c;一个是pcb整体标注&#xff0c;一个是pcb部分截图。 整体标注有6个分类&#xff0c;开路&#xff0c;短路等都已经标注&#xff0c;标注格式为xml&#xff0c;每个文件夹下有100多张…

html内嵌其他网页iframe

在很多情况下&#xff0c;需要将其他网页内嵌到自己的网页&#xff0c;如&#xff1a; 只需要使用iframe标签即可&#xff0c;通过src属性指定网站地址即可&#xff0c;代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta ch…

苹果手机怎样一键删除照片:快速清理指南

在数字化时代&#xff0c;手机照片的积累如同记忆的沉淀&#xff0c;但过多无用的照片也会占据宝贵的存储空间。对于苹果手机用户来说&#xff0c;如何高效地一键删除照片是一个常见的需求。本文将介绍几种方法&#xff0c;帮助你快速清理苹果手机中的照片。 1. 使用系统相册的…

论文解析三: D2-Net 用于联合描述和检测局部特征的可训练CNN

目录 1.D2-Net摘要2.D2-Net关键点介绍3. Joint Detection and Description (联合检测和描述)3.1 Feature Extraction3.2 Feature Detection3.2.1 Hard feature detection &#xff08;硬特征检测&#xff09;3.2.1 Soft Feature Detection&#xff08;软特征检测&#xff09; 3…

如何在VScode中加入系统安装好的python环境

在vscode的ipynb文件中&#xff0c;加入的环境总是找不到自己电脑当中已有的环境。这可能是由于自己电脑中的python没有安装ipynb对应的包&#xff0c;因而监测不出来。

【自动驾驶】控制算法(十二)横纵向综合控制 | 从理论到实战全面解析

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

MP2155升降压芯片全解析——概况、性能、应用电路、输出电压调节计算

MP2155概述 功能&#xff1a; MP2155是一款高效率、低静态电流的升降压转换器&#xff0c;可在高于、低于或等于输出电压的输入电压下工作。该器件为采用单节锂离子或多节碱性电池供电的产品提供电源解决方案。 数据&#xff1a; MP2155 可在 2V 至 5.5V 的输入电压下工作&am…

<<迷雾>> 第10章 用机器做一连串的加法(2)--寄存器 示例电路

使用多个触发器可以构成一个寄存器 info::操作说明 单击按钮开关产生上升沿信号, 将 D 的输入存在 Q 端 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjdmw-examples/assets/circuit/cyjsjdmw-ch10-02-register-by-multipl…