Make your owner PE Protector Part 1: Your first EXE Protector

卫星轨道坐标转换:轨道六根数到经纬高(经STK验证) a:半长轴(km)e:偏心率i:轨道倾角(度)Ω:升交点赤经(度)ω:近地点幅角(度)ν:真近点角(度) 阅读详情

Yoda's Protector v1.01 - Free EXE Protector

Preface

This article was written to provide the better understanding to people who do not have any experience in this field. I am not going to describe about PE structure, so I think it was explained enough in Matt Pietrek’s articles in MSDN. I strongly recommend to read his article before continuing to read this article if you don’t have any previous experience with PE structure. You could find useful the relevant reference link at the end of article.

This article will appear in three parts:

  1. Your first EXE Protector

    This part will describe how to make a powerful EXE protector and packer by using Visual C++ Win32 Programming.

  2. Support OCX, DLL, and SCR

    This part will introduce to include other PE type in additional to EXE file type. It will explain some tricks which you should know for OCX and DLL protecting.

  3. Use Cryptography API

    This part will demonstrate how to use Microsoft Cryptography API function to encrypt and decrypt PE section information.

This article contains yoda’s protector source from version 1.01 to 1.03. It is first time people can look at its source after six month of appearance on Web. It is based on [6] yoda’s Crypter assembly source by Danilo Bzdok and compression source from [7] UPX library by Markus F.X.J. Oberhumer & László Molnár and [9] aPLib compression library by Joergen Ibsen. Thus, we should appreciate them for helping me to create this tool. I also should be grateful to people for trying and testing it on different Windows versions around the world. I think this article will be a small present to all people who involve and assist to make yoda’s protector.

Contents

Introduction

The Portable Executable format is standard format under Microsoft Windows NT ® operating system. It contains information for code, data, resource, dynamic link libraries importation. It is modifiable by using recent powerful debuggers such as OllyDbg or SoftICE with a little knowledge about assembly language. It causes to waste the time of software development companies to obtain money for their productions. Therefore, they are led to purchase the tool like EXE protector to prevent from illegal copy. My idea is what will happen if every person has owner EXE protector. Cracker person will face different EXE protector with different methods. Thus, I think each of us can have their own EXE protector.

A short aspect about PE Structure

The Portable Executable includes information for the MS-DOS, the Windows NT, and Sections. This information is provided for Windows Operating System to allocate memory, import dynamic link libraries, and perform code.

Table 1
MS-DOS informationIMAGE_DOS_HEADER
MS-DOS Stub Program
Windows NT informationPE Signature ("PE")
IMAGE_FILE_HEADER
IMAGE_OPTIONAL_HEADER
Sections information

IMAGE_SECTION_HEADER[0]
…
IMAGE_SECTION_HEADER[n]

SECTION[0]
…
SECTION[n]

You can find more about PE file format in [1] “Microsoft Portable Executable and Common Object File Format Specification”. Matt Pietrek clarifies it enough in [2] “Peering Inside the PE: A Tour of the Win32 Portable Executable File Format”, and [3a/b] “An In-Depth Look into the Win32 Portable Executable File Format”.

Moreover, PEView [4] by Wayne J. Radburn will help you to find all aspects about PE file format.

Figure 1

PEView

All the required data structures for PE file format are included in winnt.h file inside your Visual C++. IMAGE_DOS_HEADER, IMAGE_NT_HEADERS, IMAGE_SECTION_HEADER structures represent all you need to work with PE file format. The relevant information for these structures could be found in [5] MSDN library.

Open PE files

We have to load PE file format to memory for working with its information. Some Windows API function will help us do it very easy: CreateFile(), GetFileSize(), GlobalAlloc(), ReadFile(), CloseHandle().

I make a class to work with PE files. It helps me to open files and put DOS header, NT headers, Section Headers, and Sections into separate places in memory and then rebuild all as new PE files.

class PEStructure 
{
private:
      DWORD ReservedHeaderSize;
      DWORD ReservedHeaderRO;
public:
      DWORD                   dwRO_first_section;
      IMAGE_DOS_HEADER        image_dos_header;
      char                    *reservedheader;
      IMAGE_NT_HEADERS        image_nt_headers;
      IMAGE_SECTION_HEADER    image_section_header[MAX_SECTION_NUM];
      char                    *image_section[MAX_SECTION_NUM];
      void OpenFileName(char* FileName);
      void UpdateHeaders(BOOL bSaveAndValidate);
      void UpdateHeadersSections(BOOL bSaveAndValidate);
      void Free();
};

OpenFileName() will open PE files to place in image_dos_header, reservedheader, image_nt_headers, image_section_header[], and image_section[]. All PE structures will abstract by this function in my tool.

void PEStructure::OpenFileName(char* FileName)
{
      hFile=CreateFile(FileName,
                       GENERIC_READ,
                       FILE_SHARE_WRITE | FILE_SHARE_READ,
                       NULL,OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,NULL);
      if(hFile==INVALID_HANDLE_VALUE)
      {
            ShowErr(FileErr);
            return;
      }
      dwFsize=GetFileSize(hFile,0);
      if(dwFsize == 0)
      {
            CloseHandle(hFile);
            ShowErr(FsizeErr);
            return;
      }
      dwOutPutSize=
          dwFsize+IT_SIZE+DEPACKER_CODE_SIZE+ALIGN_CORRECTION;
      pMem=(char*)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
                                             dwOutPutSize);
      if(pMem == NULL)
      {
            CloseHandle(hFile);
            ShowErr(MemErr);
            return;
      }
      ReadFile(hFile,pMem,dwFsize,&dwBytesRead,NULL);
      CloseHandle(hFile);
      CopyMemory(&image_dos_header,pMem,sizeof(IMAGE_DOS_HEADER));
      ReservedHeaderRO=sizeof(IMAGE_DOS_HEADER);
      ReservedHeaderSize=
             image_dos_header.e_lfanew-sizeof(IMAGE_DOS_HEADER);
      reservedheader=new TCHAR[ReservedHeaderSize];
      CopyMemory(&image_nt_headers,
                 pMem+image_dos_header.e_lfanew,
                 sizeof(IMAGE_NT_HEADERS));
      dwRO_first_section = 
           image_dos_header.e_lfanew + sizeof(IMAGE_NT_HEADERS);
      UpdateHeadersSections(TRUE);
}

Verify if PE file is valid

It is important to verify whether the file is a Win32 Portable Executable file by checking e_magic of image_dos_header and Signature of image_nt_header to prevent of unpredictable fault.

if(PEfile.image_dos_header.e_magic!='ZM')
{
      GlobalFree(pMem);
      CloseHandle(hFile);
      if(MakeBackup) DeleteFile(szFnameBackup);
      ShowErr(PEErr);
      return;
}
if(PEfile.image_nt_headers.Signature!='EP')
{
      GlobalFree(pMem);
      CloseHandle(hFile);
      if(MakeBackup) DeleteFile(szFnameBackup);
      ShowErr(PEErr);
      return;
}

Make Extra Section

There is a trick inside yoda’s Protector to create extra section for protection and unpacking purposes. Visual C++ aids it to make this extra part without using of assembler compiler and linker. If you look at PE_LOADER_CODE(), subroutine inside the CryptStuff.cpp you will find what I am talking about. This is same as the method that was done by Danilo Bzdok in his [6] yoda’s Crypter. Of course, he did it only by using assembly language in MASM32 without any high level language. I made GetFunctionRVA(), GetFunctionSize() ,and CopyFunction() to rob code from PE_LOAD_CODE() and use it to create additional section for target PE file.

DWORD GetFunctionRVA(void* FuncName)
{
      void *_tempFuncName=FuncName;
      char *ptempFuncName=PCHAR(_tempFuncName);
      DWORD _jmpdwRVA,dwRVA;
      CopyMemory(&_jmpdwRVA,ptempFuncName+1,4);
      dwRVA=DWORD(ptempFuncName)+_jmpdwRVA+5;
      return(dwRVA);
}
DWORD GetFunctionSize(void* FuncName)
{
      DWORD dwRVA=GetFunctionRVA(FuncName);
      char* pFuncBody=PCHAR(dwRVA);
      UCHAR _temp;
      bool notEnd=TRUE;
      char *DepackerCodeEnd=new TCHAR[10];
      DWORD l=0;
      do
      {
            CopyMemory(&_temp,pFuncBody+l,1);
            if(_temp==0xC3)
            {
                  CopyMemory(DepackerCodeEnd,pFuncBody+l+0x01,10);
                  DepackerCodeEnd[9]=0x00;
                  if(strcmp(DepackerCodeEnd,"ETGXZKATZ")==0)
                  {
                        notEnd=FALSE;
                  }
            }
            l++;
      }while(notEnd);
      return(l);
}

GetFunctionRVA() will seek to Relative Virtual Address of specific subroutine to use by GetFunctionSize() and CopyFunction(). GetFunctionSize() will return the size of target routine to be exploited by CopyFunction(). It seeks a keyword (“ETGXZKATZ”) to calculate routine size. Finally, CopyFunction() is a complete routine to steal all code from PE_LOADER_CODE() subroutine to place in packed PE file.

char* CopyFunction(void* FuncName)
{
    DWORD dwRVA=GetFunctionRVA(FuncName);
    DWORD dwSize=GetFunctionSize(FuncName);
    char* pFuncBody=PCHAR(dwRVA);
    char* filebuff=new TCHAR[dwSize+1];
    CopyMemory(filebuff,pFuncBody,dwSize);
    return(filebuff);
}

This method can illuminate in the following code:

char    *pDepackerCode;
DWORD    DEPACKER_CODE_SIZE;
…
DEPACKER_CODE_SIZE=GetFunctionSize(PE_LOADER_CODE);
pDepackerCode=new TCHAR[DEPACKER_CODE_SIZE];
pDepackerCode=CopyFunction(PE_LOADER_CODE);
…

void PE_LOADER_CODE()
{
      _asm
      {
      //----------------------------------------------------------
      //-------------- START OF THE PE LOADER CODE ---------------
DepackerCode:
      …
      …
      …
DepackerCodeEND:
    RET
    //"ETGXZKATZ" <<-- KEY WORD
    INC EBP     //'E'
    PUSH ESP    //'T'
    INC EDI     //'G'
    POP EAX     //'X'
    POP EDX     //'Z'
    DEC EBX     //'K'
    INC ECX     //'A'
    PUSH ESP    //'T'
    POP EDX     //'Z'
    }
}

Pack and Crypt Sections

UPX compressor source [7] code is an alternative choice to pack sections of PE files. I use [8] LZO data compression library by Markus F.X.J. Oberhumer to pack code and data section. Polymorphism encryption and decryption method [6] by Danilo Bzdok is simple and good enough to crypt PE section by some modification in C++ language as you see inside EncryptBuff() and DecryptBuff() in PER.CPP.

This protector separates Sections in different allocation parts of memory. Afterwards it packs and crypts part of sections by CompressPE() and CryptPE().

//------ ENCRYPT THE SECTIONS -----
// generate PER
PEfile.UpdateHeadersSections(TRUE);
SecEncryptBuff=new TCHAR[SEC_PER_SIZE];
SecDecryptBuff=new TCHAR[SEC_PER_SIZE];
MakePER(SecEncryptBuff,SecDecryptBuff,SEC_PER_SIZE);
CopyMemory(pDepackerCode+dwRO_SEC_DECRYPT,
           SecDecryptBuff,
           SEC_PER_SIZE);    
// encrypt !
CompressPE(pMem);
CryptPE(pMem);
RemoveSectionNames(pMem);
newsection.Misc.VirtualSize=DepackCodeVirtualSize+0x2000;
PEfile.image_section_header[
        PEfile.image_nt_headers.FileHeader.NumberOfSections-1]
        .Misc.VirtualSize = newsection.Misc.VirtualSize;
PEfile.UpdateHeadersSections(FALSE);
//---------------------------------

LZO data compression library [8] has compressor source in C++ and decompressor source in both C++ and assembly. Hence, we have all sources to pack in high level language and unpack in low level language. I used lzo1x_999_compress_level() from LZO library to compress sections inside CompressPE() and its assembly source lzo1f_decompress_asm_fast_safe() to decompress sections inside _DecompressPE() in assembly source of PE_LOADER_CODE().

It is important to pay attention to image_nt_headers.OptionalHeader.SectionAlignment and image_nt_headers.OptionalHeader.FileAlignment to prevent of Win32 incompatible file error in Windows version above Windows 98. Variables in IMAGE_SECTION_HEADER should be adapted to file-alignment and section-alignment. I reserved UpdateHeadersSections() function to retrieve and rebuilt all PE file format structures.

void PEStructure::UpdateHeadersSections(BOOL bSaveAndValidate)
{
    DWORD i;
    if(bSaveAndValidate)//TRUE = data is being retrieved
    {
        DWORD SectionNum = PEfile.image_nt_headers
                           .FileHeader.NumberOfSections;
        CopyMemory(&image_dos_header,pMem,sizeof(IMAGE_DOS_HEADER));
        ReservedHeaderSize = image_dos_header.e_lfanew –
                             sizeof(IMAGE_DOS_HEADER);
        if((ReservedHeaderSize&0x80000000)==0x00000000)
        {
            CopyMemory(reservedheader, 
                       pMem+ReservedHeaderRO,
                       ReservedHeaderSize);
        }
        CopyMemory(&image_nt_headers,
             pMem+image_dos_header.e_lfanew,
             sizeof(IMAGE_NT_HEADERS));
     dwRO_first_section = image_dos_header.e_lfanew +
                            sizeof(IMAGE_NT_HEADERS);
       CopyMemory(&image_section_header, 
                  pMem+dwRO_first_section, 
                  SectionNum*sizeof(IMAGE_SECTION_HEADER));
       for(i=0;i< SectionNum;i++)
       {
           image_section[i] = (char*)GlobalAlloc(
                GMEM_FIXED | GMEM_ZEROINIT,
            PEAlign(image_section_header[i].SizeOfRawData,
                PEfile.image_nt_headers.OptionalHeader.FileAlignment));
           CopyMemory(image_section[i],
               pMem + image_section_header[i].PointerToRawData,
               image_section_header[i].SizeOfRawData);
       }
    }
   else//FALSE = data is being initialized 
   {
       DWORD SectionNum = PEfile.image_nt_headers
                          .FileHeader.NumberOfSections;
       CopyMemory(pMem,
            &image_dos_header,sizeof(IMAGE_DOS_HEADER));
            ReservedHeaderSize=image_dos_header.e_lfanew –
                               sizeof(IMAGE_DOS_HEADER);
       if((ReservedHeaderSize&0x80000000)==0x00000000)
       {
          CopyMemory(pMem + ReservedHeaderRO,
                     reservedheader,
                     ReservedHeaderSize);
       }
       CopyMemory(pMem+image_dos_header.e_lfanew,
            &image_nt_headers,
            sizeof(IMAGE_NT_HEADERS));
       dwRO_first_section = image_dos_header.e_lfanew +
                            sizeof(IMAGE_NT_HEADERS);
       CopyMemory(pMem+dwRO_first_section,
                 &image_section_header,
                 SectionNum*sizeof(IMAGE_SECTION_HEADER));
       for(i=0;i< SectionNum;i++)
       {
           CopyMemory(pMem+image_section_header[i].PointerToRawData,
                      image_section[i],
                      image_section_header[i].SizeOfRawData);
       }
    }
} 

Built Import Table Directory

PE unpack section need to import two essential API functions to load dynamically all other API functions in Run-time load. LoadLibraryA() and GetProcAddress() from Kernel32.dll are vital functions to import other API function with some tricky methods. AssembleIT() is reserved to undertake this task. We should change the import table address and size for turning to new import table directory inside extra section. To retrieve the old import table, it has to reload and rebuild import table directory in the next step to perform program code. Loader section uses LoadLibraryA() and GetProcAddress() to seek relative virtual address of importation function of dynamic link libraries.

Table 2
Import Table Address ->"Kernel32.dll", 0x00
 LoadLibrary_RVA
 GetProcessAddres_RVA
 0x00,0x00
LoadLibrary_RVA ->0x00,0x00,"LoadLibraryA"
GetProcessAddres_RVA ->0x00,0x00,"GetProcessAddress"

Reload Import Table and API Redirection

It is important to protect import table directory from reverse engineering process. Danilo Bzdok has used technical methods to destroy import thunk data and crypt import information in [6] yoda’s Crypter. This part is retrievable again by loader code section. I applied his methods in my PE Protector with bringing some part of code to C and remind other part in assembly. ProcessOrgIT() provides all we need to do our purpose. In loader section, INIT_IMPORT_TABLE() routine implements our point about API redirection and Import table rebuilt.

Anti-debug methods

PE Protector should able to detect if program debugs and prevent from debugging. OllyDbg and SoftICE are two important debuggers that can bypass many tricks which cause to halt debuggers. However, I should introduce some simple methods to detect debuggers. I know all of these methods do not have any effect in recently added plug-ins for the mentioned debuggers.

  1. IsDebuggerPresent Windows API: IsDebuggerPresent() will return non zero value whenever the current process is running in the context of a debugger.
  2. SoftICE detection: It can find SoftICE debugger by check if NTICE driver in windows NT and SICE driver in windows 98 are active.
    if(CreateFile( "////.//NTICE", GENERIC_READ | GENERIC_WRITE, 
          FILE_SHARE_READ | FILE_SHARE_WRITE, 
          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
          NULL)!=INVALID_HANDLE_VALUE) 
    { 
        There is SoftICE NT on your system; 
    } 
    
    if(CreateFile( "////.//SICE", GENERIC_READ | GENERIC_WRITE, 
          FILE_SHARE_READ | FILE_SHARE_WRITE, 
          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
          NULL)!=INVALID_HANDLE_VALUE) 
    { 
        There is SoftICE98 on your system; 
    }
    
  3. Probe Processes: Sometimes, it needs to search for specific process or isolates to specific process. It was demonstrated how finding parent process and check if it is EXPLORER.EXE and killing all parent process except Explorer windows in sample source code. There are both C++ and assembly code inside CryptStuff.CPP to illuminate this task.
    void GetFileNameFromPath(char* szSource)
    {
          char *szTemp=strrchr(szSource,'//');    
          if(szTemp!=NULL)
          {
                szTemp++;
                DWORD l=DWORD(strlen(szTemp))+1;
                CopyMemory(szSource,szTemp,l);
          }
    }
    
    void AntiDebug()
    {
          char lpszSystemInfo[MAX_PATH];
          HANDLE hSnapshot=NULL;
          DWORD PID_child;
          DWORD PID_parent,PID_explorer;
          HANDLE hh_parnet = NULL;
          PROCESSENTRY32    pe32 = {0};
          pe32.dwSize = sizeof(PROCESSENTRY32);//0x128;
          PID_child=GetCurrentProcessId();//getpid();
          hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
          if (Process32First(hSnapshot, &pe32))
          {
                while (Process32Next(hSnapshot, &pe32))
                {
                      GetFileNameFromPath(pe32.szExeFile);
                      CharUpperBuff(pe32.szExeFile,strlen(pe32.szExeFile));
                      if(strcmp(pe32.szExeFile,"EXPLORER.EXE")==0)
                      {
                            PID_explorer=pe32.th32ProcessID;
                      }
                      if(pe32.th32ProcessID==PID_child)
                      {
                            PID_parent=pe32.th32ParentProcessID;
                      }
                }
          }
          if(PID_parent!=PID_explorer)
          {
                hh_parnet= OpenProcess(PROCESS_ALL_ACCESS, 
                                        TRUE, PID_parent);
                TerminateProcess(hh_parnet, 0);
          }
          else
          {
                MODULEENTRY32    me32 = {0};
                me32.dwSize = sizeof(MODULEENTRY32);
                hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
                            PID_explorer);
                if (Module32First(hSnapshot, &me32))
                {
                      do
                      {
                            if(PID_explorer==me32.th32ProcessID)
                            {
                                  GetWindowsDirectory(lpszSystemInfo,
                                   MAX_PATH+1);
                                  strcat(lpszSystemInfo,"//");
                                  strcat(lpszSystemInfo,"EXPLORER.EXE");
                          CharUpperBuff(me32.szExePath,
                                        strlen(me32.szExePath));
                                  if(strncmp(me32.szExePath,
                                              lpszSystemInfo,
                                        strlen(lpszSystemInfo)))
                                  {
                                     GetFileNameFromPath(me32.szExePath);
                                     if(strcmp(me32.szExePath,
                                        "EXPLORER.EXE")==0)
                                     {
                                        hh_parnet= 
                                            OpenProcess(PROCESS_ALL_ACCESS,
                                              TRUE, PID_explorer);
                                        TerminateProcess(hh_parnet, 0);
                                     }
                                  }
                            }
                      }while (Module32Next(hSnapshot, &me32));
                }
          }
    }
    

    This code will not work under Windows NT 4.0 because of absence CreateToolhelp32Snapshot(), Process32First(), Process32Next(), Module32First(), Module32Next(). But all of these API functions could be build by undocumented API function from NTDLL.DLL. You can take a look at [10] ‘Windows NT (2000) Native API reference’ by Gary Nebbett.

    Furthermore, I recommend using [11] Process Explorer by Mark Russinovich to explore all running processes in your systems. It will help to understand them better.

    Figure 2

    Process Explorer

Eliminate unnecessary data

Some time you need to clean all unnecessary data such as debug information, relocation section and make small DOS header and remove MS-DOS stub Program. You should reserve these items in your PE Protector with some considerations. For instance, Relocation section do not have any effect in running EXE files but it plays an important role in OLE-Active Controls and Dynamic Link Libraries.

Sample code

The project compiles with Visual C++ .NET 2003 and doesn’t require any spare tools. It works under all Windows version except Windows NT 4.0 and Windows 95.

Conclusion

This article and its source could be an introduction to PE protector tools and demonstrating how these tools works. I hope it covers the absence of this kind of interesting topics and tools in open source area.

References

[1] "Microsoft Portable Executable and Common Object File Format Specification", Microsoft Corporation, Revision 6.0, February 1999.

[2] " Peering Inside the PE: A Tour of the Win32 Portable Executable File Format", Matt Pietrek, MSDN Library, March 1994.

[3a] "An In-Depth Look into the Win32 Portable Executable File Format", part 1, Matt Pietrek, MSDN Magazine, February 2002.

[3b] "An In-Depth Look into the Win32 Portable Executable File Format", part 2, Matt Pietrek, MSDN Magazine, March 2002.

[4] PEview Version 0.67, Wayne J. Radburn.

[5] MSDN Library, Microsoft Corporation, April 2003.

[6] yoda’s Crypter, Danilo Bzdok.

[7] UPX, the Ultimate Packer for eXecutables, Markus F.X.J. Oberhumer & László Molnár.

[8] LZO real-time data compression library, Markus F.X.J. Oberhumer.

[9] aPLib compression library, Joergen Ibsen.

[10] "Windows NT (2000) Native API reference", Gary Nebbet.

[11] Process Explorer, Mark Russinovich.

Ashkbiz Danehkar


Click here to view Ashkbiz Danehkar's online profile.


Other popular articles:

2、探索谷歌云平台(GCP):入门指南 本文全面介绍了谷歌云平台(GCP)的入门知识,涵盖其全球基础设施、核心服务和使用方法。内容包括GCP区域与可用区结构、创建免费账户、配置计算资源(如GCE虚拟机)、存储类型(PD、Filestore、GCS)、网络架构(VPC)、组织与项目管理、身份访问控制(IAM),以及计算、存储、数据库、大数据和人工智能等各类云服务。文章还提供了资源规划、安全管理和成本控制等实用建议,帮助用户快速上手并高效利用GCP构建可扩展的云解决方案。 阅读详情

相关推荐

从零构建:如何用MATLAB工具箱打造你的第一个多体动力学仿真模型

本文详细介绍了如何使用MATLAB的Simscape Multibody工具箱从零开始构建多体动力学仿真模型,特别适合初学者学习倒立摆系统的建模与仿真。文章涵盖环境准备、坐标系设置、物理模型构建、参数化建模及性能优化等关键步骤,帮助工程师快速掌握这一强大的仿真工具。

water的专栏 965

自删除技术小记:Gary Nebbett

以前看书的时候摘录的笔记,经典的自删除方法,可以当历史故事看看 :) Gary Nebbett1曾提出一种方法,利用系统的一个特点来达到目的。 #include<windows.h> int main(int argc,char *argv[]) { char buf[MAX_PATH]; HMODULE module; module=GetModuleHandle(0); GetModuleFileName(module,buf,MAX_PATH); .

break_cat的博客 366

RK3576开发板ROS2部署实战:从Buildroot配置到Hello World Demo

本文详细介绍了在RK3576开发板上部署ROS2的完整实战流程。从Buildroot工程配置、集成ROS2依赖,到搭建Docker交叉编译环境、处理编译难题,最终完成系统镜像打包并在板端成功运行Talker-Listener Demo。该指南旨在帮助开发者深入理解嵌入式机器人系统的构建链,实现从底层到应用的完全掌控。

mac99的博客 1159

Make your owner PE Protector

 Preface This article was written to provide the better understanding to people who do not have any experience in this field. I am not going to describe about PE structure, so I think it was expla

5165

from pointnet2_ops import pointnet2_utils 安装过程

pointnet2_ops

goodgoodstudy___的博客 8363

华为Watch的ECG功能技术分析

华为Watch的ECG(心电图)功能通过硬件传感器、算法优化和医疗认证的结合,实现了对心脏电活动的监测和房颤(AFib)等心律失常的预警。采用医疗级ECG模拟前端芯片(AFE),如TI(德州仪器)的ADS1292R等,支持低噪声、高采样率(通常≥200Hz)。结合PPG(光学心率)数据交叉验证,提高检测可靠性(如ECG和PPG心率不一致时触发警告)。通过RR间期变异性判断心律是否规则,识别房颤(AFib)的典型特征(如不规则不规则心律)。结合加速度计数据,识别手臂运动导致的信号失真,动态调整算法参数。

xu_wenming的博客 6447

VC实现程序自删除(三种方法)

1、Gary Nebbett的方法Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者。乃NT系统一等一的高手。下面就分析一些他的这段代码,这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了:#include int main(){ HMODULE module = GetModuleHandle

Koma的主页 6404

ControlRig蓝图节点对应代码(自用)

用于通过python生成ControlRig蓝图节点,非完整

dicha9的博客 426

精妙代码 (转)

精妙代码 (转)[@more@]下面的代码由Gary Nebbett写就.Gary Nebbett乃是windows NT/2000 NATIVE api REFERENCE的作者.乃NT系统一等一的高手.下面就分析一些他的这段...

csd3176的博客 169

手把手教你学simulink实例--Simulink在电动汽车故障诊断与预测中的应用仿真

通过上述步骤,我们成功实现了基于Simulink的电动汽车故障诊断与预测仿真。该系统能够全面评估故障诊断与预测算法的性能,验证其在不同故障场景下的有效性,并通过优化设计提高系统的可靠性和安全性。引入智能算法:结合人工智能技术,实现更智能的故障诊断与预测。扩展功能:增加对多种车型和故障类型的支持,提升系统通用性。实验验证:将仿真模型应用于实际硬件,进行实验验证,评估其在实际工况下的表现。

MHD0815的博客 256

【四足机器人项目实战】MIT无刷电机FOC硬件电路设计

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、MCU最小系统--STM32F446RE1.usb串口通讯连接口+程序下载连接口2.MCU电源滤波二、磁编码器角度传感器三、三相驱动桥四、CAN通讯收发器电路五、温度ADC检测六、电源滤波及分压电路1、DC电源输入端2、DC电源滤波电路3、DC电源分压电路4、三相绕线接线端总结参考资料 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对

qq_35635374的博客 7068

模块删除页代码

include "../include/head.php"; include "../include/cn.php"; include"../include/fun.php"; $sql="delete from single_content where id=".$_GET["id"]; if (mysql_query($sql)) {  box("信息删除成功","manage.p

萌球球Q 685

1. BES2700ZP概述

恒玄BES2700采用RTX5操作系统,配合mindmics算法或者自研算法。

雪飞_海 4476

在PROCESS没有结束前就将启动PROCESS的EXE文件删除

下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者.乃NT系统一等一的高手.下面就分析一些他的这段代码. 这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了. int main(int argc, char *argv[]) {     HMODULE module = G

tlovexyj的专栏 1208

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

再说程序运行后自删除的方法(C++源代码)

JohnChen分析了一下Gary Nebbett写的一段程序自删除的程序。是很精妙的一段代码,精妙之处在于其进程尚在,但可执行文件已经被删除了。 我前段时间也写了一段自删除代码,不过没有那么高深,只是利用了批处理的功能,在程序的最后调用我这个函数,就能够将自己删除。现在把函数代码贴出来。 void SelfDelete() {static char templ[] = ":Repeat\r\n"...

技术代码资料库 632

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

程序自删除实现 可用的SDK的

我找自删除的东西 一找一大片,结果一个能直接用的也没有, 我用下面这个倒是可以如果有必要可以试一下.这个代码是我从 草草的SEU_PEER中拿出来的BOOL SelfDelete()...{    TCHAR szModule [MAX_PATH],          szComspec[MAX_PATH],          szParams [MAX_PATH];    // get 

冷风 1708

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

微软技术日报 11-09:.NET 8 与 9 明日同时停止支持,注册表编辑器出了 WinUI 3 版

今天这四条消息的共同点是收口。.NET 8 和 9 的支持期到点,注册表编辑器的新界面只放在仓库里给人看,GitHub 把一类危险触发器按住默认,微软在安全报告里把防线从地址黑名单挪到行为。收口并不等于关门。.NET 10 还在支持期里,被按住的触发器可以用策略按文件放回来,实验室里的样例随时可能变成产品。区别在于这些动作要有人签字,不再是默认开着。如果今天只做一件事,去看一眼构建机上的 .NET 版本。明天之后,8 和 9 的漏洞补丁不会再来了。

海盗Sharp的博客 394

AI驱动数据处理的安全边界:行业现状、风险权衡与本地化实践路径

本文基于第三方数据,分析AI用于数据处理的安全议题。大模型应用加速普及,但伴随数据出境、影子AI、幻觉与成本失控等风险。行业共识指向“脚本复用”路径:将分析逻辑本地化固化,实现数据可控、结果可复现、成本可降。产品如数以轻舟提供本地处理、多模型接入与一次付费永久使用方案。建议企业从数据落点、可控性、可复现性与合规性四维度评估选型,推动AI在安全边界内释放价值。

数据矿工-数据化运营博客 331

微软技术日报 11-08:Foundry 与 Entra 各挂一个 10.0 分漏洞,Foundry 接 fal 五款视频模型

这一周的动作可以分成两类。一类在收。Copilot 从电视上退场,搜索里的 AI 改成可选,云端漏洞只发通知不收补丁。共同点是承认铺得太开,代价比预期高。另一类在放。Foundry 一次摆上五个视频模型,容器版应用网关一个入口挂 64 个 MCP 服务器。共同点是把能力做成可组合的积木,让使用者按需挑。两个方向背后是同一个判断。把能力塞到每一个界面上,短期看覆盖率高,长期要解释为什么删不掉。新的做法是先给一个能关的开关,再谈覆盖。对每天写代码的人来说,今天有两样现成的东西可以试。

海盗Sharp的博客 439

微软技术周报 11-02~11-09:VS Code 混装 Claude 与 Codex、EF Core 11 静默改行为、.NET 11 倒计时

11 月 6 日,Power Platform 通过消息中心通知管理员,Copilot Studio、Power Automate 和 Power Apps 里所有跑在 Anthropic Claude、xAI Grok 以及旧版 GPT 上的 prompt,12 月 2 日自动迁移到 GPT-6 系列,档位价格不变,模型选择收窄到一条产品线。效果是这样的:让 Claude 评审一个 Copilot chat 写出的方案,或者把同样的任务交给 Codex,两边并排跑在同一个会话里。更要紧的是下周的时间线。

海盗Sharp的博客 1014

MAI-Cyber-1 深度解析:微软首个网络安全专用模型

微软没有去做"更大的安全大模型",而是用一颗 137B 总参、仅 5B 激活的稀疏 MoE 专用模型,配上 90/10 的"小模型铺量、大模型兜底"路由,在 CyberGym 基准上拿到 95.95% 的同时把成本砍掉一半——这标志着 AI 安全从"通用模型加提示词"进入了"专用模型加系统工程"的时代。

Simple_Pure的博客 336

微软技术日报 2026-11-14:Aion Instruct 接替 Phi Silica、1% 投毒与 SCKit 蠕虫

微软在 11 月 13 日公布了 Windows 本地语言模型的换代计划,Phi Silica 交棒给 Aion Instruct。同一周里,微软安全团队连发两项研究,证明训练环节掺进极少量数据就能让编码智能体执行攻击者的命令;微软威胁情报则拆解了一个借 ScreenConnect 反向打技术员的蠕虫工具包。Azure 这边,ARM 的 MCP 服务器从只读扩到了可写。下面按技术线逐条展开。

海盗Sharp的博客 304

微软输入法标点乱跳解决方案

微软拼音输入法常因“中文输入时使用英文标点”开关被意外开启,导致标点自动切换为英文且快捷键失效。本文提供一键批处理脚本,通过修改注册表(HKCU\Software\Microsoft\InputMethod\Settings\CHS)强制锁定中文标点,覆盖多个相关键值,确保设置持久生效。相比手动操作,该方案可抵御更新、同步等导致的配置重置,提升稳定性。执行后需重启输入法或系统以使更改生效,建议提前备份注册表。

谙弆悕博士的技术博客! 372

微软2026年11月补丁星期二解析:1094个 CVE、Outlook 零日 CVE-2026-124194 与修复优先级

微软11月补丁星期二修复1094个 CVE,唯一在野利用的 Outlook 零日 CVE-2026-124194 只评为“中等”,修复随 Office 更新下发、不在 Windows 累积更新里。本文整理漏洞分布、严重级漏洞分类处置与三档修复优先级。

SplashtopLoki的博客 242

【第 008 讲】在终端中运行 Python 程序:交互模式与脚本模式 | 绝对路径与相对路径 | 以模块方式运行 | 常见报错的识别与排查

本文系统讲解在终端中运行 Python 程序的方式:从交互模式与脚本模式讲起,梳理绝对路径与相对路径的运行写法及 cd、dir 等命令的用法;进而讲解以模块方式运行的特点与字节码缓存的产生;最后通过路径、拼写、标点三类典型报错,帮助读者掌握读懂报错、定位并修复错误的排查思路。

大模型全栈工程师 · Thanks_ks 800

情感交互机器人融资,四川具身科技的「爱湫」登场

当前人形机器人的主流战场是工业、仓储、巡检这些「干活」的场景,而「爱湫」把重心放在了「陪伴」上——通过面部投影和情绪识别,让机器人和人之间多一层情感层面的交互。情感交互机器人的市场,其实一直存在,只是过去被「能干活」的主流叙事盖住了。它主推的产品「爱湫」,是一款主打情感交互的人形机器人,搭载 3D 投影面部技术,情感交互机器人的逻辑,是面向养老陪伴、文旅服务、展厅导览这类「不要求重体力、但要求互动感」的场景。真正的考验不在发布会,而在它能不能在真实的养老和陪伴场景里,被用户用起来、留下来。

jushenAGI的博客 299
上一篇: 在win2000、winXP下看 **********
下一篇: 安装SATA硬盘
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值