PEiD中unUPX.dll(UPX unpacker)插件的逆向分析笔记

UPXUnPacKer:专业UPX脱壳工具实战解析 在逆向工程与二进制分析领域,脱壳(Unpacking)是还原被压缩或混淆的可执行文件原始形态的关键步骤。UPX作为最广泛使用的开源可执行压缩工具之一,其加壳机制虽公开透明,但在实际应用中常因版本差异、平台适配及人为修改而呈现出复杂多变的特征。为应对这一挑战,UPXUnPacKer应运而生——它是一款专为识别并剥离UPX壳体设计的专业工具,具备高度自动化、跨平台兼容和灵活策略选择等核心能力。 阅读详情
 

就是试试逆向,找了个10多KB的,不会太花时间也不会没劲.第一次搞逆向,没什么经验,也不知到底该做到什么程度,不足之处请见谅,多多指教.

Exports中有三个函数,
LoadDLL
DoMyJob
DllEntryPoint

其中LoadDLL是返回此DLL于PEiD中的名称,如下

 

代码:

char* __stdcall LoadDLL ()
{
  return "Unpacker for UPX";
}

DLLEntryPoint就不用说了,可以参考PEiD的插件编写资料,这里就不放于重点了,此文探查去UPX壳的过程


先附上要用到的两个函数,DoMyJob()中的,先提前放上来

 

代码:

////////////////////////////////////////////////////////
//
//  _IsFileExisting
//  return : TRUE  if File existing
//           FALSE if File not existing
//
////////////////////////////////////////////////////////

BOOL __stdcall _IsFileExisting (char *psFN)
{
  WIN32_FIND_DATA    WFD;
  if (FindFirstFile (psFN, &WFD) == INVALID_HANDLE_VALUE)
  {
    return FALSE;
  }
  return TRUE;
}

////////////////////////////////////////////////////////
//
//  _CalcAddrOffset
//  两次用到用来计算偏移量
//  return : Address (used by SetFilePointer)
//
////////////////////////////////////////////////////////
int __stdcall _CalcAddrOffset (  char*  pPartOfFileImage,
                int    nBaseAddr,
                int    word_404460)
{
  int*  pn  = 0;
  int    n  = 0;
  int    i  = 0;

  pn = (int*)pPartOfFileImage;
  n = nBaseAddr;
  pn += 3;
  for ( i = 0; i < word_404460; i++ )
  {
    if ( *pn <= n )
    {
      if ( (*pn + *(pn + 1)) > n )
      {
        n = (n - *pn) + *(pn + 2);
      }
    }
    pn += 0xA;
  }
  return n;
}
//


下面是DoMyJob()~~~



 

代码:

BOOL __stdcall DoMyJob (int    UnknownArg1,
            HWND  hWnd,
            char  *pFileName
            )
{
  unsigned long  sBuffer[2]      = {0};
  unsigned long  *lpBuffer      = &sBuffer[0];
  unsigned long  ulOffset      = 0;  //PE文件偏移0x3C处的值,频繁用来计算其他偏移值
  unsigned long  ulBuff        = 0;  //EBP_14,临时变量,存储读取的数据
  int        nFileSize      = 0;  //文件大小
  int        nUPXSign      = 0;  //EBP_28    ulOffset + _CalcAddrOffset    UPX的标识
  int        nStr1AddrInFile    = 0;  //EBP_2C    输出的文件中将写入Str1[0x31]的地址
  int        nStr1FullSize    = 0;  //EBP_30    sizeof (Str1 + 填补的0)
  int        nPEHeaderAddr    = 0;  //EBP_18    ulOffset + 0x34    0x00400000
  int        nHeapSize      = 0;  //EBP_1C    ulOffset + 0x50    输出文件的完整内存映像大小
  int        nBaseAddr      = 0;  //EBP_10
  int        i          = 0;  //temp var
  int        n          = 0;  //temp var
  int        *pn          = 0;  //temp var
  int        nPatch        = 0xFEEB;  //用来改写程序内存的一个值
  const  int    nCounter      = 3;  //循环次数
  HANDLE      hMemBlock      = 0;
  HANDLE      hFile        = 0;
  char      *lpCaption      = 0;
  char      sPartOfFileImage[150]  = {0};  //压缩文件的内存映像
  char      *pPartOfFileImage  = &sPartOfFileImage[0];
  char      *p          = 0;  //temp var
  unsigned long  lNumberOfBytesRead  = 0;
  LPDWORD      lpNumberOfBytesRead  = &lNumberOfBytesRead;
  STARTUPINFO          SI    = {0};  //EBP_78
  PROCESS_INFORMATION      PI    = {0};  //EBP_88
  CONTEXT            CT    = {0};
  static  char  sNewFileName[]    = "unpacked.exe";
  static  char  sExistingFileName[]  = "unpacked_.exe";

  //一些用来改写的值
  static  char  sChar1[]      =  "/xE0/x00/x00/xE0";
  static  char  sChar2[]      =  "/x40/x00/x00/xC0";
  static  char  sCharunpacked[]    =  "unpacked";
  static  char  sCharpusher[]    =  "_pusher_";
  static  char  Str1[0x31]      =  "/x00/x8D/x40/x00/x5F/x70/x75/x73/x68/x65/x72/x5F/x00/x8D/x40/x00"
                      "/x34/x41/x2B/x01/x58/x44/x2B/x01/x88/x30/x2B/x01/x90/x30/x2B/x01"
                      "/x5C/x44/x2B/x01/x60/x44/x2B/x01/x94/x30/x2B/x01/x54/x44/x2B/x01";



  if ( pFileName == NULL )
  {
    MessageBox ( hWnd, "no file ?", lpCaption, MB_OK|MB_APPLMODAL );
    return FALSE;
  }

  hFile = CreateFile ( pFileName,
             GENERIC_READ,
             FILE_SHARE_READ,
             NULL,
             OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL,
             NULL
             );
  
  if ( hFile == INVALID_HANDLE_VALUE )
  {
    MessageBox ( hWnd, "FAILED (can't open file)", lpCaption, MB_OK|MB_APPLMODAL );
    return FALSE;
  }
  //_OpenFile

  if (( nFileSize = GetFileSize ( hFile, NULL )) <= 0x258 )
  {
    MessageBox ( hWnd, "FAILED (file size too small)", lpCaption, MB_OK|MB_APPLMODAL );
    return FALSE;
  }
  //_IsFileSizeRight

  ReadFile ( hFile, lpBuffer, 2, lpNumberOfBytesRead, NULL );
  if ( *lpBuffer != IMAGE_DOS_SIGNATURE)
  {
    MessageBox ( hWnd, "FAILED (invalid EXE)", lpCaption, MB_OK|MB_APPLMODAL );
    return FALSE;
  }
  //_IsFileWin32

  SetFilePointer  ( hFile, 0x3C, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &ulOffset, 4, lpNumberOfBytesRead, NULL );
  SetFilePointer  ( hFile, ulOffset, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &ulBuff, 4, lpNumberOfBytesRead, NULL );
  if ( ulBuff != IMAGE_NT_SIGNATURE )
  {
    MessageBox ( hWnd, "FAILED (invalid PE)", lpCaption, MB_OK|MB_APPLMODAL );
    return FALSE;
  }
  //_IsFileValidPE

  SetFilePointer  ( hFile, ulOffset + 0x16, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &ulBuff, 2, lpNumberOfBytesRead, NULL );
  if (( ulBuff &= 0x2000 ) == 0x2000 )
  {
    MessageBox ( hWnd, "I'm sorry but this unpacker won't work with .dll files", lpCaption, MB_OK|MB_APPLMODAL );
    return FALSE;
  }
  //_IsFileNotDLL

  /*
  if ( nFileSize > ulOffset )
  {
    return FALSE;
  }
  */
  //loc_402376

  SetFilePointer  ( hFile, ulOffset + 6, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &ulBuff, 2, lpNumberOfBytesRead, NULL );

  //
  SetFilePointer  ( hFile, ulOffset +0xF8, NULL, FILE_BEGIN );
  ReadFile    ( hFile, pPartOfFileImage, 0x28 * 3, lpNumberOfBytesRead, NULL );
  //_ReadPartOfFileIntoMem

  pn      = (int*)&sPartOfFileImage[0];
  nStr1AddrInFile  = int (( ulBuff << 3 ) * 5 + ulOffset + 0xF8);
  nStr1FullSize  = (*(pn + 0x5) - 0x1D) - nStr1AddrInFile + 1;

  SetFilePointer  ( hFile, ulOffset + 0x34, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &nPEHeaderAddr, 4, lpNumberOfBytesRead, NULL );

  SetFilePointer  ( hFile, ulOffset + 0x50, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &nHeapSize, 4, lpNumberOfBytesRead, NULL );

  SetFilePointer  ( hFile, ulOffset +0x28, NULL, FILE_BEGIN );
  ReadFile    ( hFile, &nBaseAddr, 4, lpNumberOfBytesRead, NULL );

  n = _CalcAddrOffset ( pPartOfFileImage, nBaseAddr, nCounter);

  SetFilePointer  (hFile, n, NULL, FILE_BEGIN);
  ReadFile    (hFile, &nUPXSign, 2, lpNumberOfBytesRead, NULL);
  CloseHandle    (hFile);

  // UPX的标识:
  if ((nUPXSign -= 0xE8) == 0)
  {
  }
  else if ((nUPXSign -= 0x60A8) == 0)
  {
  }
  else if ((nUPXSign -= 0x5CD0) == 0)
  {
  }
  else if ((nUPXSign -= 0x2A00) == 0)
  {
  }
  else
  {
    MessageBox (hWnd, "No UPX signature were found...", lpCaption, MB_OK|MB_APPLMODAL);
    if ( MessageBox (hWnd, "Still wanna try to unpack it ?", "(if you are sure its UPX)", MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) == IDNO)
    {
      return FALSE;
    }
  }

  GetStartupInfo (&SI);
  if (CreateProcess (  pFileName,
            NULL,
            NULL,
            NULL,
            FALSE,
            CREATE_SUSPENDED,
            NULL,
            NULL,
            &SI,
            &PI
            ) == 0 )
  {
    MessageBox (hWnd, "Failed to run program", lpCaption, MB_OK|MB_APPLMODAL);
    return FALSE;
  }

  // 找OEP:
  p = (char*) nBaseAddr + nPEHeaderAddr + 0x14E;
  for (i = 0; i < 0x50; i++)
  {
    ReadProcessMemory (PI.hProcess, p, &ulBuff, 2, lpNumberOfBytesRead);
    if (ulBuff == 0xE961)
    {
      break;
    }
    else if (ulBuff == 0xE9CC)
    {
      break;
    }
    else if (ulBuff == 0xE960)
    {
      break;
    }
    p++;
    if(i == 0x4F) //循环结束还没有找到OEP
    {
      MessageBox (hWnd, "were unable to find OEP, could be a modified version.", "closing down...", MB_OK|MB_APPLMODAL);
      TerminateProcess (PI.hProcess, 0);
      return FALSE;
    }
  }

  //loc_402605:
  p += 2;
  ReadProcessMemory (PI.hProcess, p, &ulBuff, 4, lpNumberOfBytesRead);
  ulBuff = ulBuff + (unsigned long)p + 4 - nPEHeaderAddr;
  p--;
  WriteProcessMemory (PI.hProcess, p, &nPatch, 2, lpNumberOfBytesRead);
  CT.ContextFlags = CONTEXT_FULL;

  do{
    ResumeThread (PI.hThread);
    Sleep (1);
    SuspendThread (PI.hThread);
    GetThreadContext (PI.hThread, &CT);
  } while ((DWORD)p != CT.Eip );

  if (_IsFileExisting (pFileName) == 1)
  {
    if (MessageBox (hWnd, "A file called unpacked.exe already exists, do you want to overwrite it ?", "Overwrite ?", MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) != IDYES)
    {
      MessageBox (hWnd, "Terminating Process...", lpCaption, MB_OK|MB_APPLMODAL);
      TerminateProcess (PI.hProcess, 0);
      return FALSE;
    }
    DeleteFile (&sNewFileName[0]);
  }

  //_WriteUnpackedFile:
  if (nHeapSize != 0)
  {
    hMemBlock = HeapAlloc (GetProcessHeap(), 0, nHeapSize);
    if (hMemBlock == 0)
    {
      MessageBox ( hWnd, "HeapAlloc() failed", "", MB_OK);
    }
  }

  ReadProcessMemory (PI.hProcess, (char*)nPEHeaderAddr, hMemBlock, nHeapSize, lpNumberOfBytesRead);
  hFile = CreateFile (&sNewFileName[0], 0xC0000000, 3, 0, 2, 0x80, 0);
  WriteFile (hFile, hMemBlock, nHeapSize, lpNumberOfBytesRead, 0);
  if (hMemBlock != 0)
  {
    if ( !HeapFree (GetProcessHeap(), 1, hMemBlock) )
    {
      MessageBox (hWnd, "HeapFree() failed", "", MB_OK);
    }
  }
  SetFilePointer  (hFile, ulOffset + 0x28, 0, FILE_BEGIN);
  WriteFile    (hFile, &ulBuff, 4, lpNumberOfBytesRead, 0);

  p = pPartOfFileImage;
  if (nCounter != 0)
  {
    n = 1;
    for (i = 0; i < nCounter; i++)  //nCounter = 3
    {
      strncpy (p,  &sCharunpacked[0], 8);
      *(p + 0x10) = *(p + 0x8);
      *(p + 0x11) = *(p + 0x9);
      *(p + 0x12) = *(p + 0xA);
      *(p + 0x13) = *(p + 0xB);
      *(p + 0x14) = *(p + 0xC);
      *(p + 0x15) = *(p + 0xD);
      *(p + 0x16) = *(p + 0xE);
      *(p + 0x17) = *(p + 0xF);
      if (n == 1)
      {
        *(p + 0x24) = sChar1[0];
        *(p + 0x25) = sChar1[1];
        *(p + 0x26) = sChar1[2];
        *(p + 0x27) = sChar1[3];
      }
      else
      {
        *(p + 0x24) = sChar2[0];
        *(p + 0x25) = sChar2[1];
        *(p + 0x26) = sChar2[2];
        *(p + 0x27) = sChar2[3];
      }
      n++;
      p += 0x28;
    }
  }

  SetFilePointer (hFile, ulOffset + 0xF8, 0, FILE_BEGIN);
  p = pPartOfFileImage;
  if (nCounter > 0)
  {
    for (i = 0; i< nCounter; i++)
    {
      WriteFile ( hFile, p, 0x28, lpNumberOfBytesRead, 0);
      p += 0x28;
    }
  }

  //loc_4027C1:
  GetFileSize    (hFile, 0);
  SetFilePointer  (hFile, ulOffset + 8, 0, FILE_BEGIN);
  WriteFile    (hFile, &sCharpusher, 8, lpNumberOfBytesRead, 0);
  SetFilePointer  (hFile, nStr1AddrInFile, 0, FILE_BEGIN);

  if (nStr1FullSize > 0x30)
  {
    for (i = 0; i < 0x30; i++)
    {
      WriteFile (hFile, &Str1, 1, lpNumberOfBytesRead, 0);
    }
    SetFilePointer (hFile, nStr1AddrInFile + 0x30, 0, FILE_BEGIN);
    for (i = 0; i < (nStr1FullSize - 0x30); i++)
    {
      WriteFile (hFile, "/x00", 1, lpNumberOfBytesRead, 0);
    }
  }

  n = _CalcAddrOffset ( pPartOfFileImage, nBaseAddr, nCounter);

  SetFilePointer  (hFile, n, 0, FILE_BEGIN);

  //loc_40284B:
  for (i = 0; i < 0x30; i++)
  {
    WriteFile (hFile, &Str1, 1, lpNumberOfBytesRead, 0);
  }

  CloseHandle (hFile);
  /*
  //  BOOL __stdcall _RebuildImport (HWND  hWnd,
                     int  EBP_80,
                     int  EBP_14,
                     char  *sFN,
                     int  i,
                     int  j
                     )
  //  通过ImpREC.dll修复输入表,就不弄它了

  if (_RebuildImport ( &sNewFileName, 0xA, 0) != 0 )
  {
    DeleteFile (&sNewFileName);
    MoveFile (&sExistingFileName, &sNewFileName);
    MessageBox (hWnd, "Unpacking Done (unpacked.exe)", lpCaption , MB_OK|MB_APPLMODAL);
  }
  */
  TerminateProcess (PI.hProcess, 0);
  return TRUE;
  //dump完成,但是还需要修复一下输入表
}

附件中是经注释的IDA database

UPXUnPacKer.V0.3:UPX壳快速解包工具 UPX(Ultimate Packer for eXecutables)是一款广泛使用的可执行文件压缩工具,它能够减小Windows可执行文件(.exe)以及可链接库文件(.dll)的体积。通过压缩,UPX能够有效节省磁盘空间并加快软件的分发速度。UPX通过重新编码和优化程序来实现压缩,而且它具有可逆性,即压缩后的程序可以通过UPX解压工具完全还原。UPX支持多种压缩算法,并提供了高度的压缩比和良好的压缩速度。 阅读详情

相关推荐

UPX Unpacker

一个非常好的脱壳工具。对破解等有非常好的用处,UPX Unpacker是个通用脱壳工具。

【恶意代码分析】_第一站

文章目录概述第一周阅读部分 概述   主要讲解加壳脱壳,每周讲解一种壳。   参考教材:可以买来当字典。   操作系统:Windows sp系统,Win7环境可能出现执行失败等问题。 第一周   本节目标:了解UPX壳解压缩过程、查找用UPX夹克软件的OEP。   加壳是指:运行时压缩,即对可执行程序资源进行压缩。 加壳是使用算法压缩程序的exe、dll文件,用户执行的只是外壳程序(压缩后的程序)。不同之处在于该压缩文件可独立运行、程序自动隐蔽解压,加壳工具在文件头放一段指令告诉CPU怎么解压程序,运行壳

soldi_er的博客 1376

upx脱壳机--用于upx类脱壳

用于脱upx类壳,简单的脱壳工具,在Windows环境下可以使用

实验四:使用UPX加壳与脱壳

实验四:使用UPX加壳与脱壳 报告人姓名:苏煜程 学号:031803108 一、实验目的 了解程序加壳、脱壳原理 掌握PE文件结构 学习利用UPX Shell、LoardPE、IDA等工具完成软件的加、脱壳操作 二、实验题目 UPX加壳:对crackme加上UPX壳,用 LordPE 或 PEiD 工具查看加壳前后的变化 UPX脱壳:用UPX Unpacker对已加壳的 crackme.exe 程序进行脱壳 手动脱壳:使用ESP定律和Ollydbg工具对crackme.exe进行手工脱壳 IDA静

kelxLZ的博客 8531

UPXUnPacKer.V0.3

简单方便脱upx壳,而且无需脱客后的修复。操作简单方便,不用安装,放心使用。

脱壳示例,包括PEid、PECompact、ASPack_Unpacker、UpxUnpacker等工具

脱壳示例程序,包含三个加了不同壳的示例程序,以及相应的解壳工具。 查壳工具:PEiD 解壳工具: PECompact、ASPack_unpacker、UpxUnpacker 适合想学习加壳解壳的初学者。

完美UPX脱壳机UPXUnPacKer最新版:高效脱除UPX壳的工具

完美UPX脱壳机UPXUnPacKer最新版:高效脱除UPX壳的工具 【下载地址】完美UPX脱壳机UPXUnPacKer最新版 UPXUnPacKer是一款专为完美脱除UPX壳而设计的工具,经过优化,能够高效处理UPX压缩文件,帮助用户轻松去除壳层,便于软件分析与研究。该工具操作简单,只需选择文件并点击脱壳按钮,即可在指...

gitblog_06762的博客 2143

UPX Unpacker.exe

UPX Unpacker.exe

【亲测免费】 完美UPX脱壳机UPXUnPacKer最新版

完美UPX脱壳机UPXUnPacKer最新版 【下载地址】完美UPX脱壳机UPXUnPacKer最新版 UPXUnPacKer是一款专为完美脱除UPX壳而设计的工具,经过优化,能够高效处理UPX压缩文件,帮助用户轻松去除壳层,便于软件分析与研究。该工具操作简单,只需选择文件并点击脱壳按钮,即可在指定目录获取脱壳后的文件。...

gitblog_06762的博客 668

35款最新自动脱壳工具合集

本人收集的比较好用的自动脱壳工具,共35款,一包打尽所有工具.

完美UPX脱壳机UPXUnPacKer最新版

完美脱UPX壳的工具 但凡是脱壳机基本都报毒的,使用时请将杀软及其他监控软件关闭,否则打不开的

upx脱壳工具_攻防世界simple_unpack_逆向之旅003

攻防世界simple_unpack_逆向之旅003前言一、使用exeinfo PE查看该文件二、使用upx脱壳2.使用ida打开脱壳处理后的文件总结 前言 先给出题目的链接: https://adworld.xctf.org.cn/task/answer?type=reverse&number=4&grade=0&id=5077&page=1 题目说是个加了个壳的二进制文件 一、使用exeinfo PE查看该文件 如上图所示,检测到了upx的壳。 二、使用upx脱壳 指

weixin_43281394的博客 7870

一款专用脱upx脱壳工具

UPX的壳可以用其自身命令脱: upx -d 文件名 但对于处理过的UPX壳,此命令就不好用了。这时,可以用upxfix工具来修复文件,再用unxfix自带的upx来脱。

UPX脱壳详解

介绍CTF比赛中常见的upx壳类型

m0_62280492的博客 8688

unUPX 1.x - 3.x_unpacker_

Unpacker for UPX created in delphi.

自动查壳脱壳工具,该软件能够检查程序的编译器信息、是否加壳、入口点地址、输出表 输入表等等PE信息,可以帮助开发人员对程序进行破

自动查壳脱壳工具,该软件能够检查程序的编译器信息、是否加壳、入口点地址、输出表 输入表等等PE信息,可以帮助开发人员对程序进行破姐,同时还可以提取PE文件中的资源,可以提取图片、EXE、压缩包、MSI、SWF等等资源,并且还具备非常强悍的可鉴定多种文件类别的能力,能够全面兼容,其中包括bmp、.jpg、.mov、.mp4、.vpx、.CRX、.skn、.dcu、.obj、.nup、.vhd、.tar、.gma、.mts、res、.tiff、.7z、.rar等一系列的多种文件格式。除此之外,exeinfope还能够给予用户引导脱壳方法,这对用户快速了解加密程序采用的加密方式并加以学习利用有很大帮助,也可说是查壳破解脱壳领域用户的得力帮手。

[De1CTF2019]REVERSE的Re_Sign

[De1CTF2019]REVERSE的Re_Sign . . 照例下载附件,扔到 exeinfope 中查看信息: . . 提示 UPX 壳,但是好像无法使用 UPX -D 来脱壳: . . 那么先尝试一下手动脱壳,扔入 OD 中,利用 ESP 脱壳定律: . . 然后嘛~脱壳后导入表乱了,用 ImportREC 修复也修复不了,(我曾想着自己修复,但还是太年轻了 ~ ^ ~): 然后经友人推荐使用了 UpxUnpacker.exe ,直接脱壳且能运行!不得不说这个几百KB的工具真的专业,希

沐一 · 林 的博客 1601

手把手教你分析解决Innovus DRC Violation 和Antenna Effect Violation

数字IC后端设计培训教程之手把手教你分析解决Innovus DRC Violation 和Antenna Effect Violation

weixin_37584728的博客 2942

Updated UnUPX PEiD Plugins by _pusher_

Just updated UnUPX now it unpacks UPX 2.0 too  and remember to have imprec.dll in plugin directory. Link: url:://www.secretashell.com/codomain/peid/plugins/unupx.dll

Linhanshi Blog 2218

使用python读取卫星测高数据并做相应的处理

5.在python处理结果如下,最大的优点就是比matlab快30-40倍。4.进行粗差的如NaN值,还有进行3倍方差进行对粗差处理。1.首先遍历卫星数据的文件,挨个读取每个数据。有问题,请各位读者及时告知,一起完善内容。3.进行下一步,筛选在研究区域的数据。4.进行按天求平均和按月求平均。2.读取数据主体代码。

爱下去更难! 1133

激光雷达点云可视化:Open3D与PCL实战

激光雷达点云可视化:Open3D与PCL实战 ,人工智能,计算机视觉,大模型,AI,该文围绕激光雷达点云可视化,介绍了Open3D与PCL的实战应用。先阐述点云基础概念、特点及可视化意义,接着讲解Open3D的简介、环境配置,以及其在点云读取、显示、颜色设置、下采样和滤波等方面的实战操作,还介绍了PCL的基础、环境配置及相关实战,包括点云读取、显示、颜色设置、下采样和滤波,同时对比了两者的易用性、功能覆盖、性能和适用场景,给出综合实战案例与常见问题解决方法,为点云可视化处理提供了全面指导。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 12万+
上一篇: 代码库之八-信息输出类(0.1)
下一篇: 系统自带扑克牌资源动态链接库cards.dll逆向分析笔记
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值