C#ConvertIntPtrtoint我在动态调用WindowsAPI。我在网上找到了一些执行此操作的代码,我非常感兴趣。至少可以说,这个想法本身很棒。但是,我似乎无法让它适用于我的代码。动态调用的参数类型是string、stringint[],我想使用API??GetThreadContext,参数是pInfo.hThred和refctx(如下图)。API调用GetThreadContext(pInfo.hThread,refctx);上面的代码将调用GetThreadContextAPI(假设它已在我的项目中声明)——并且工作正常。然而,动态调用的美妙之处在于不需要声明。所以,我尝试动态调用:ctx=newCONTEXT{ContextFlags=0x10007};PROCESS_INFORMATIONpInfo;CInvokeAPI.Invoke("kernel32","GetThreadContext",pInfo.hThread,ctx);这里的问题是我不知道如何传递参数ctxPassedastypeint因为它是一个结构体。请参阅下面的其他代码[StructLayout(LayoutKind.Sequential)]structCONTEXT{publicuintContextFlags;不安全的固定字节未使用[160];公共单位Ebx;公共单位Edx;公共单位Ecx;公共单位Eax;不安全的固定字节unused2[24];}[StructLayout(LayoutKind.Sequential)]structPROCESS_INFORMATION{publicIntPtrhProcess;公共IntPtrhThread;公共intdwProcessId;公共intdwThreadId;}调用API动态类usingSystem;使用System.Runtime.InteropServices;使用系统文本;/**Title:CInvokeAPI.cs*Description:CallAPIbynameimplementationinpurelymanagedC#(no'unsafe'messhere).**开发者:affixiate*评论:如果你使用这个代码,我需要你给我学分。*/publicstaticclassCInvokeAPI{//////在内存中生成一个新的、无垃圾的可收集字符串。将其与Unicode“W”API一起使用。//////Unicode字符串。///新分配的字符串在内存中的地址。使用后记得释放它。公共静态intStringToPtrW(stringtheString){returnStringToPtr(Encoding.Unicode.GetBytes(theString));}//////在内存中生成一个新的、无垃圾的可收集字符串。将其与ANSI“A”API一起使用。//////ANSII字符串。///新分配的字符串在内存中的地址。使用后记得释放它。publicstaticintStringToPtrA(stringtheString){returnStringToPtr(Encoding.ASCII.GetBytes(theString));}//////用于分配内存的内部方法。//////字节缓冲区。///新分配内存的地址。使用后记得释放它。privatestaticintStringToPtr(byte[]buf){return(int)GCHandle.Alloc(buf,GCHandleType.Pinned).AddrOfPinnedObject();}//////调用指定的WindowsAPI。//////库的名称。///函数的名称。///参数。///如果函数成功则为真,否则为假。publicstaticboolInvoke(stringlibraryName,stringfunctionName,paramsint[]args){/*完整性检查。*/IntPtrhLoadLibrary=Lo广告图书馆(图书馆名称);如果(hLoadLibrary==IntPtr.Zero)返回false;IntPtrhGetProcAddress=GetProcAddress(hLoadLibrary,functionName);如果(hGetProcAddress==IntPtr.Zero)返回false;//为stdcall和WinAPI函数的参数分配足够的内存IntPtrhMemory=VirtualAlloc(IntPtr.Zero,1024*1024,MEM_COMMIT|MEM_RESERVE,MEM_EXECUTE_READWRITE);如果(hMemory==IntPtr.Zero)返回false;IntPtrhMemoryItr=hMemory;//前置stdcall标头签名Marshal.Copy(newbyte[]{0x55,0x89,0xE5},0,hMemoryItr,0x3);hMemoryItr=(IntPtr)((int)hMemoryItr+0x3);//遍历传入的参数并将它们以相反的顺序放入堆栈for(inti=(args.Length-1);i>=0;i--){Marshal.Copy(newbyte[]{0x68},0,hMemoryItr,0x1);hMemoryItr=(IntPtr)((int)hMemoryItr+0x1);Marshal.Copy(BitConverter.GetBytes(args[i]),0,hMemoryItr,0x4);hMemoryItr=(IntPtr)((int)hMemoryItr+0x4);}米arshal.Copy(newbyte[]{0xE8},0,hMemoryItr,0x1);hMemoryItr=(IntPtr)((int)hMemoryItr+0x1);Marshal.Copy(BitConverter.GetBytes((int)hGetProcAddress-(int)hMemoryItr-0x4),0,hMemoryItr,0x4);hMemoryItr=(IntPtr)((int)hMemoryItr+0x4);//清理堆栈Marshal.Copy(newbyte[]{0x5D,0xC2,0x4,0x0/*<=ImadeaLOL.*/},0,hMemoryItr,0x4);//如果要在此处添加更多ASM代码,请不要忘记递增:hMemoryItr=(IntPtr)((int)hMemoryItr+0x4);try{varexecuteAsm=(RunAsm)Marshal.GetDelegateForFunctionPointer(hMemory,typeof(RunAsm));执行汇编();}赶上{返回假;}//清理我们分配给脏工作的内存VirtualFree(hMemory,0,MEM_RELEASE);返回真;}//ReSharper禁用不一致命名privateconstuintMEM_RELEASE=0x8000;私有结构MEM_COMMIT=0x1000;私有结构MEM_RESERVE=0x2000;私有结构MEM_EXECUTE_READWRITE=0x40;//ReSharper休息oreInconsistentNaming//我自己的性感委托:[UnmanagedFunctionPointer(CallingConvention.StdCall,SetLastError=true)]privatedelegatevoidRunAsm();//使用的WinAPI:[DllImport("kernel32.dll",SetLastError=true)]privatestaticexternboolVirtualFree(IntPtrlpAddress,UInt32dwSize,uintdwFreeType);[DllImport("kernel32.dll",SetLastError=true)]privatestaticexternIntPtrVirtualAlloc(IntPtrlpAddress,UInt32dwSize,uintflAllocationType,uintflllImport);kernel32.dll",SetLastError=true)]privatestaticexternIntPtrLoadLibrary(stringlpFileName);[DllImport("kernel32.dll",SetLastError=true,CharSet=CharSet.Ansi)]privatestaticexternIntPtrGetProcAddress(IntPtrhModule,字符串lpProcName);}你能使用IntPtr.ToInt32方法吗?这应该适用于第一个参数,但不确定结构转换。也许查看这篇文章了解如何将结构转换为整数的想法。更新:没有直接的C#等同于C#中的VarPtr,但我确实找到了此处引用的手册(以及对其功能的解释……听起来与这篇文章中对VarPtr的解释类似)。这是代码的摘录。它可能对你有用:publicstaticintVarPtr(objecte){GCHandleGC=GCHandle.Alloc(e,GCHandleType.Pinned);intgc=GC.AddrOfPinnedObject().ToInt32();GC.Free();返回GC;注意:此功能有一些潜在的缺陷,如本文所述。以上就是C#学习教程:C#将IntPtr转int的全部内容分享。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
