标签: delphi源码

Delphi-条件判断那些事

之前照着天书夜读,用Delphi来弄了下循环体,现在就来弄一下条件判断吧.首先肯定是我们经常看见的IF语句咯. 1234567891011121314Var I: Integer; Begin I:= 99; If (I> 0)And (I< 0) Then Writeln('I>0') Else If (I> 10)And (I< 100) Then Writeln('I>10 and I<100') Else Writeln('I>100'); End. 反汇编出来会是什么样子的呢? 1234567891011121314151617181920212223242526272829303132Project5.dpr.12: I:= 99;004AC44C B863000000 mov eax,$00000063Project5.dpr.13: If (I> 0)And (I< 0) Then004AC451 85C0 test eax,eax004AC453 7E1F jle $004ac474004AC455 85C0 test eax,eax004AC457 7D1B jnl $004ac474Project5.dpr.14: Writeln('I>0')004AC459 A1DC314B00 mov eax,[$004b31dc]004AC45E BAC4C44A00 mov edx,$004ac4c4004AC463 E874BAF5FF call @Write0UString004AC468 E8BF89F5FF call @WriteLn004AC46D E83E7FF5FF call @_IOTest004AC472 EB3E jmp $004ac4b2Project5.dpr.16: If (I> 10)And (I< 100) Then004AC474 83F80A cmp eax,$0a004AC477 7E20 jle $004ac499004AC479 83F864 cmp eax,$64004AC47C 7D1B jnl $004ac499Project5.dpr.17: Writeln('I>10 and I<100')004AC47E A1DC314B00 mov eax,[$004b31dc]004AC483 BAD8C44A00 mov edx,$004ac4d8004AC488 E84FBAF5FF call @Write0UString004AC48D E89A89F5FF call @WriteLn004AC492 E8197FF5FF call @_IOTest004AC497 EB19 jmp $004ac4b2Project5.dpr.19: Writeln('I>100');004AC499 A1DC314B00 mov eax,[$004b31dc]004AC49E BA04C54A00 mov edx,$004ac504004AC4A3 E834BAF5FF call @Write0UString004AC4A8 E87F89F5FF call @WriteLn004AC4AD E8FE7EF5FF call @_IOTest 我们这里就容易得出来Delphi里面IF语句的结构了.判断1不满足就跳————————-|满足条件代码 |[无条件Jmp到所有判断外] |[判断2] <——|………………………………………..就是这样的在IF的反汇编上面 和 书中的VC反汇编出来的代码差不多.接下来就是看switch语句(Delphi里面的Case): 12345678910111213141516171819202122232425Var I: Integer; Begin I:= 9; Case I Of 0: Writeln('0'); 1: Writeln('1'); 2: Writeln('2'); 3: Writeln('3'); 4: Writeln('4'); 5: Writeln('5'); 6: Writeln('6'); 7: Writeln('7'); Else Writeln('0'); End; End. 反汇编一下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778Project5.dpr.12: I:= 9;004AC44C B809000000 mov eax,$00000009Project5.dpr.13: Case I Of004AC451 83F807 cmp eax,$07004AC454 0F8703010000 jnbe $004ac55d004AC45A FF248561C44A00 jmp dword ptr [eax*4+$4ac461]004AC461 81C44A009EC4 add esp,$c49e004a004AC467 4A dec edx004AC468 00BBC44A00D8 add [ebx-$27ffb53c],bh004AC46E C44A00 les ecx,[edx+$00]004AC471 F5 cmc 004AC472 C44A00 les ecx,[edx+$00]004AC475 0FC54A0029 pextrw ecx,qword ptr [edx+$00],$29004AC47A C54A00 lds ecx,[edx+$00]004AC47D 43 inc ebx004AC47E C54A00 lds ecx,[edx+$00]Project5.dpr.15: Writeln('0');004AC481 A1DC314B00 mov eax,[$004b31dc]004AC486 66BA3000 mov dx,$0030004AC48A E8DDADF5FF call @Write0WChar004AC48F E89889F5FF call @WriteLn004AC494 E8177FF5FF call @_IOTest004AC499 E9D7000000 jmp $004ac575Project5.dpr.17: Writeln('1');004AC49E A1DC314B00 mov eax,[$004b31dc]004AC4A3 66BA3100 mov dx,$0031004AC4A7 E8C0ADF5FF call @Write0WChar004AC4AC E87B89F5FF call @WriteLn004AC4B1 E8FA7EF5FF call @_IOTest004AC4B6 E9BA000000 jmp $004ac575Project5.dpr.19: Writeln('2');004AC4BB A1DC314B00 mov eax,[$004b31dc]004AC4C0 66BA3200 mov dx,$0032004AC4C4 E8A3ADF5FF call @Write0WChar004AC4C9 E85E89F5FF call @WriteLn004AC4CE E8DD7EF5FF call @_IOTest004AC4D3 E99D000000 jmp $004ac575Project5.dpr.21: Writeln('3');004AC4D8 A1DC314B00 mov eax,[$004b31dc]004AC4DD 66BA3300 mov dx,$0033004AC4E1 E886ADF5FF call @Write0WChar004AC4E6 E84189F5FF call @WriteLn004AC4EB E8C07EF5FF call @_IOTest004AC4F0 E980000000 jmp $004ac575Project5.dpr.23: Writeln('4');004AC4F5 A1DC314B00 mov eax,[$004b31dc]004AC4FA 66BA3400 mov dx,$0034004AC4FE E869ADF5FF call @Write0WChar004AC503 E82489F5FF call @WriteLn004AC508 E8A37EF5FF call @_IOTest004AC50D EB66 jmp $004ac575Project5.dpr.25: Writeln('5');004AC50F A1DC314B00 mov eax,[$004b31dc]004AC514 66BA3500 mov dx,$0035004AC518 E84FADF5FF call @Write0WChar004AC51D E80A89F5FF call @WriteLn004AC522 E8897EF5FF call @_IOTest004AC527 EB4C jmp $004ac575Project5.dpr.27: Writeln('6');004AC529 A1DC314B00 mov eax,[$004b31dc]004AC52E 66BA3600 mov dx,$0036004AC532 E835ADF5FF call @Write0WChar004AC537 E8F088F5FF call @WriteLn004AC53C E86F7EF5FF call @_IOTest004AC541 EB32 jmp $004ac575Project5.dpr.29: Writeln('7');004AC543 A1DC314B00 mov eax,[$004b31dc]004AC548 66BA3700 mov dx,$0037004AC54C E81BADF5FF call @Write0WChar004AC551 E8D688F5FF call @WriteLn004AC556 E8557EF5FF call @_IOTest004AC55B EB18 jmp $004ac575Project5.dpr.31: Writeln('0');004AC55D A1DC314B00 mov eax,[$004b31dc]004AC562 66BA3000 mov dx,$0030004AC566 E801ADF5FF call @Write0WChar004AC56B E8BC88F5FF call @WriteLn004AC570 E83B7EF5FF call @_IOTest 在这里我们看到了一个Delphi的优化,它首先把I和7比,如果大于就直接跳到else语句那里.如果小于等于,我们看到是无条件Jmp到一个I为等间距偏移的地方,也就是每个writeln语句是等大小的.要是我们改成不是01234567呢?大家自己试一下,不是等距case代码还是没有变.而VC里面会怎么样?cmp->je->cmp->je->cmp->je就是这样不停的对比,如果相等就跳.这样符合我们思维一些.转自https://www.cnblogs.com/huangjacky/archive/2010/02/04/1663847.html For循环

学习外挂的外挂源代码

01:可得到在网页中输入的用户名和密码的源代码 VC源代码02:传2脱机源代码 VC源代码03:传2机器人源代码 VC源代码04:封包截取的源码,值得学习 VC源代码05:神迹外挂挂源码 VC源代码06:系统加速源代码 DELPHI源代码07:传2外挂源码 ,功能丰富,是不可多得的源码 DELPHI源代码08:神迹脱机外挂源码 DELPHI源代码09:内存修改器源代码 VB源代码10:Winsock 详细使用例程 VB源代码11:内存搜索及修改源代码 VB源代码12:QQ消息自动发送器,有许多API操作值得学习 VB源代码13:读写INI文件的操作,值得学习 VB源代码14:截取封包的操作 VB源代码15:又一个内存修改器的源代码 VB源代码16:剑侠补血源码 VB源代码17:绿光抓包器,很好用 BC源代码18:封包截取源代码 VC源代码19:CS最有名的作敝器ORC9源码 VC源代码20:mu窗口化源码 VC源代码21:系统加速源码 VB源代码22:魔力宝贝和石器时代解图工具源码 VC源代码23:刀剑online 内存查看(HP,MP等) VB源代码24 :巨好的传奇2外挂 VC源代码25:巨好的龙族外挂源码 VB源代码26:传奇封包分析器 VB源代码27:DiabloII的外挂源代码 VC源代码28:JoolzCheat源码(著名游戏CS1.5版作弊器ogc-para源码) VC源代码29:传奇自动发言外挂 VC源代码30:盛大传奇外挂源码 VC源代码31:新大话西游经典系列源代码 VC源代码32:自动释放ASN聚气外挂源代码 VC源代码33:天翼脱机外挂源码(强力推荐) DELPHI源代码34:内存查找修改器 (和FPE GE一样,查找速度极快) DELPHI源代码35:又一个内存查找修改器 DELPHI源代码36:内存查找修改 DELPHI源代码37:BlowFish解密函数 DELPHI源代码38:lose-v0.41beta-win32-src DELPHI源代码39:传奇VB代码-Group.dat文件解密代码 VB源代码40:刀剑自动补血 VB源代码41:金庸小外挂 VB源代码42:腾讯QQ游戏–对对碰外挂制作教程详解 VB源代码43:APIhook DELPHI源代码44:APIHOOK VC源代码45:一个呼出热键的示例 DELPHI源代码46:mir外挂 易语言47:奇迹登陆器 VB源代码48:QQ对对碰小外挂 DELPHI源代码49:好像是封神ONLINE的东西 VC源代码50:一个极好的钩子教材 易语言51:传世地图 BC源代码52:奇迹登录器的E源码 易语言53:对对碰挂机 VC源代码54:库库神仙的防大补贴 DELPHI源代码55:扫雷外挂 DELPHI源代码56:毁灭天使2源代码 易语言 全部源代码下载地址:链接: https://pan.baidu.com/s/1Nr_ujf-OWGVZh1DrYdd6SA 提取码: amnp 复制这段内容后打开百度网盘手机App,操作更方便哦

在游戏中切出外挂delphi代码

需要用DLL方式调用:这是DLL的DPR文件: 1234567891011121314151617181920212223242526library Hook32; { Important note about DLL memory management: ShareMem must be thefirst unit in your library's USES clause AND your project's (selectProject-View Source) USES clause if your DLL exports any procedures orfunctions that pass strings as parameters or function results. Thisapplies to all strings passed to and from your DLL--even those thatare nested in records and classes. ShareMem is the interface unit tothe BORLNDMM.DLL shared memory manager, which must be deployed alongwith your DLL. To avoid using BORLNDMM.DLL, pass string informationusing PChar or ShortString parameters. } usesSysUtils,Forms,Classes,myDLl in 'myDLl.pas' {Form1}; {$R *.res} exportsHookOn,HookOff; begin{Application.Initialize;Application.Run; }end. 这是DLL的PAS文件: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142unit myDLl; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; typeTForm1 = class(TForm)Button1: TButton;Edit1: TEdit;Memo1: TMemo;procedure Button1Click(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure FormDestroy(Sender: TObject);procedure FormActivate(Sender: TObject);private{ Private declarations }public{ Public declarations }end; varForm1: TForm1;function HookProc(nCode:Integer;WParam: WPARAM;LParam:LPARAM):LRESULT;stdcall;function HookOn(lpHwnd:HWND;lpType:Longint):Longint;stdcall;export;function HookOff:Boolean;stdcall;export; implementation{type KeyboardBytes=recordkbArray:array[0..255] of byte;end;} varhHk: HHOOK=0;hMOUSEHk: HHOOK=0;mhwnd:HWND=0;bShow:Boolean=False;myKey:Byte=VK_F7;kbArray:TKeyboardState;hThread: Cardinal;hmod: Pointer; //HinstancehProcessId: Cardinal; // KeyHookStruct:^THardwareHookStruct;mMode:Integer; {$R *.dfm} function HookProc(nCode:Integer;WParam: WPARAM;LParam:LPARAM):LRESULT;stdcall;beginResult :=0; if nCode<0 thenResult := CallNextHookEx(hHk,nCode,WParam,LParam)elsebeginGetKeyboardState(kbArray); if (bShow=False) And (kbArray[myKey]=1) thenbeginbShow:=True;Form1:=TForm1.Create(Application);ShowCursor(true);try// Form1.Caption :='我的DLL中的窗体!';// LockWindowUpdate(mhwnd);/// SetParent(Form1.Handle,mhwnd);// MoveWindow(Form1.Handle,1,1,2,2,True);// UpdateWindow(Form1.Handle);// UpdateWindow(mhwnd);SetWindowPos(Form1.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE);// UpdateWindow(mhwnd);// mMode:=GetMapMode(GetDC(mhwnd));// SetMapMode(GetDC(Form1.Handle),mMode);// UpdateWindow(Form1.Handle);// SetWindowLong(Form1.Handle,GWL_STYLE,GetWindowLong(mhwnd, GWL_STYLE)); Result :=1;SuspendThread(hThread);Form1.ShowModal;ShowCursor(true);ResumeThread(hThread);kbArray[myKey] := 0;SetKeyboardState(kbArray); finallyForm1.Free;end;endelsebeginResult := CallNextHookEx(hHk,nCode,WParam,LParam);end;end;end; function HookOn(lpHwnd:HWND;lpType:Longint): Longint;stdcall; export;beginmhwnd:=lpHwnd;if hHk<>0 then UnHookWindowsHookEx(hHk);hThread :=GetWindowThreadProcessId(mhwnd,hmod);// hProcessId:=cardinal(hmod);// Sleep(200);hHk :=SetWindowsHookEx(lpType,@HookProc,hInstance,hThread); // WH_KEYBOARDResult :=hHkend; function HookOff:Boolean;stdcall; export;beginif hHk<>0 thenbeginUnHookWindowsHookEx(hHk);hHk :=0;Result :=true;endelseResult :=false;end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);beginbShow:=False;end; procedure TForm1.FormDestroy(Sender: TObject);beginbShow:=False;end; procedure TForm1.Button1Click(Sender: TObject);beginForm1.close;end; procedure TForm1.FormActivate(Sender: TObject);beginShowCursor(true);end; end. 这是调用的程序PAS 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ExtCtrls; typeTForm1 = class(TForm)procedure FormCreate(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction); private{ Private declarations }public{ Public declarations }end; varForm1: TForm1;function HookOn(lpHwnd:HWND;lpType:Longint):Longint;stdcall;external 'HOOK32.DLL' name 'HookOn';function HookOff:Boolean;stdcall;external 'HOOK32.DLL' name 'HookOff';implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject);varhHandle:HWND;hProID:HWND;hThrID:HWND;h1:HWND;begin//这些只是自身程序的,没什么用。hHandle:=Application.Handle;hProID:=GetCurrentProcessId();hThrID:=GetCurrentThreadId();h1:=FindWindow(NIL,'你的程序');//这是窗口的句柄,要自己找到后,填写入。HookOn(h1,WH_KEYBOARD);end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);beginhookoff;end; end.

delphi如何在Ring3下跨进程获取DLL信息

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250unit APIUnit;{ GetProcessModuleHandle API Unit Ring3调用NtQueryInformationProcess实现跨进程获取DLL句柄 }interfaceUSES Winapi.Windows,System.SysUtils;type USHORT = Word; UNICODE_STRING = packed Record Length : USHORT; MaximumLength: USHORT; Buffer : PWideString; end; RTL_USER_PROCESS_PARAMETERS = packed record Reserved1 : array[0..15] of Byte; Reserved2 : array[0..9] of Pointer; ImagePathName: UNICODE_STRING; CommandLine : UNICODE_STRING; end; PRTL_USER_PROCESS_PARAMETERS = ^RTL_USER_PROCESS_PARAMETERS; _PEB_LDR_DATA = record Length: ULONG; Initialized: BOOLEAN; SsHandle: pointer;//PVOID; InLoadOrderModuleList: LIST_ENTRY; InMemoryOrderModuleList: LIST_ENTRY; InInitializationOrderModuleList: LIST_ENTRY; end {_PEB_LDR_DATA}; PEB_LDR_DATA = _PEB_LDR_DATA; PPEB_LDR_DATA = ^_PEB_LDR_DATA; _LDR_MODULE = record InLoadOrderModuleList: LIST_ENTRY; InMemoryOrderModuleList: LIST_ENTRY; InInitializationOrderModuleList: LIST_ENTRY; BaseAddress: pointer; EntryPoint: pointer; SizeOfImage: ULONG; FullDllName: UNICODE_STRING; BaseDllName: UNICODE_STRING; Flags: ULONG; LoadCount: SmallInt; TlsIndex: SmallInt; HashTableEntry: LIST_ENTRY; TimeDateStamp: ULONG; end {_LDR_MODULE}; LDR_MODULE = _LDR_MODULE; PLDR_MODULE = ^_LDR_MODULE; _PEB_FREE_BLOCK = record Next:Pointer; Size:ULONG; end; PPEB_FREE_BLOCK = ^_PEB_FREE_BLOCK; PEB = packed record InheritedAddressSpace:Boolean;// 00h ReadImageFileExecOptions:Boolean; // 01h BeingDebugged:Boolean; //02H Spare:Boolean; Mutant:THandle; ImageBaseAddress:Pointer; LoaderData:Pointer; //0C ProcessParameters:Pointer; SubSystemData:Pointer; ProcessHeap:Pointer; FastPebLock:Pointer; FastPebLockRoutine:PPointer; FastPebUnlockRoutine:PPointer; EnvironmentUpdateCount:ULONG; KernelCallbackTable:^Pointer; EventLogSection:Pointer; EventLog:Pointer; FreeList:PPEB_FREE_BLOCK; TlsExpansionCounter:ULONG; TlsBitmap:Pointer; TlsBitmapBits:array [0..$2] of ULONG; ReadOnlySharedMemoryBase:Pointer; ReadOnlySharedMemoryHeap:Pointer; ReadOnlyStaticServerData:^Pointer; AnsiCodePageData:Pointer; OemCodePageData:Pointer; UnicodeCaseTableData:Pointer; NumberOfProcessors:ULONG; NtGlobalFlag:ULONG; Spare2:array [0..$4] of Byte; CriticalSectionTimeout:LARGE_INTEGER; HeapSegmentReserve:ULONG; HeapSegmentCommit:ULONG; HeapDeCommitTotalFreeThreshold:ULONG; HeapDeCommitFreeBlockThreshold:Ulong; NumberOfHeaps:ULONG; MaximumNumberOfHeaps:ULONG; ProcessHeaps:PPointer; GdiSharedHandleTable:Pointer; ProcessStarterHelper:Pointer; GdiDCAttributeList:Pointer; LoaderLock:Pointer; OSMajorVersion:ULONG; OSMinorVersion:ULONG; OSBuildNumber:ULONG; OSPlatformId:ULONG; ImageSubSystem:ULONG; ImageSubSystemMajorVersion:ULONG; ImageSubSystemMinorVersion:ULONG; GdiHandleBuffer:array [0..$22] of ULONG; PostProcessInitRoutine:ULONG; TlsExpansionBitmap:ULONG; TlsExpansionBitmapBits: array [0..$80] of Byte; SessionId:ULONG; end; PPEB = ^PEB; PROCESS_BASIC_INFORMATION = packed record ExitStatus : DWORD; PebBaseAddress: PPEB; AffinityMask : DWORD; BasePriority : DWORD; uUniqueProcessId: ULong; uInheritedFromUniqueProcessId: ULong; end; TProcessBasicInformation = PROCESS_BASIC_INFORMATION; function NtQueryInformationProcess( ProcessHandle: THandle; {进程句柄} ProcessInformationClass: Byte; {信息类型} ProcessInformation: Pointer; {缓冲指针} ProcessInformationLength: ULONG; {以字节为单位的缓冲大小} ReturnLength: PULONG {写入缓冲的字节数} ): DWORD; stdcall; external 'ntdll.dll';function GetProcessModuleHandle(dwProcessID:DWORD;DllName:PChar):DWORD;implementation function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean):Boolean; var TP: TOKEN_PRIVILEGES; Dummy: Cardinal; begin try TP.PrivilegeCount := 1; LookupPrivilegeValue(nil, pchar(PrivName), TP.Privileges[0].Luid); if bEnable then TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED else TP.Privileges[0].Attributes := 0; AdjustTokenPrivileges(hToken, False, TP, SizeOf(TP), nil, Dummy); except end; Result :=True; end; function EnableDebugPrivilege: Boolean; var hToken: THandle; begin Result := False; try OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken); EnablePrivilege(hToken, 'SeDebugPrivilege', True); CloseHandle(hToken); Result :=True; except end; end; function GetProcessModuleHandle(dwProcessID:DWORD;DllName:PChar):DWORD; var hProcess:DWORD; PBI:TProcessBasicInformation; r,ret:DWORD; readByte: SIZE_T; PEBType:PPEB; PLD :PPEB_LDR_DATA; PME :PLDR_MODULE; PEBDLLName:PChar; const Size:DWORD = 255; begin Result := 0; GetMem(PEBType,SizeOf(PEB)); ZeroMemory(PEBType,SizeOf(PEB)); GetMem(PLD,SizeOf(PEB_LDR_DATA)); ZeroMemory(PLD,SizeOf(PEB_LDR_DATA)); GetMem(PME,SizeOf(LDR_MODULE)); ZeroMemory(PME,SizeOf(LDR_MODULE)); GetMem(PEBDLLName,Size); try //提升进程权限 if not EnableDebugPrivilege then begin OutputDebugStringW('Do not have Debug privilege'); //无法提升调试权限 end; //如果PID为0则获取自身的伪句柄,如果不是则获取指定PID的句柄 if dwProcessID <> 0 then //打开进程,需要PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限 hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE,dwProcessID) else hProcess := GetCurrentProcess; //调用NtQueryInformationProcess获取结构信息 ret := NtQueryInformationProcess(hProcess,0,@PBI,SizeOf(PBI),@r); //正常情况下ret是0,如果不是则认为错误 if ret = 0 then begin //获取PEB结构 ReadProcessMemory(hProcess,PBI.PebBaseAddress,PEBType,SizeOf(PEB),readByte); //获取PLD结构 ReadProcessMemory(hProcess,PEBType.LoaderData,PLD,SizeOf(PEB_LDR_DATA),readByte); //获取第一个PME ReadProcessMemory(hProcess,PLD.InLoadOrderModuleList.Flink,PME,SizeOf(LDR_MODULE),readByte); //循环 while True do begin //清零缓冲区 ZeroMemory(PEBDLLName,Size); //读取buff到内存中,获取当前结构的DLL名 if not ReadProcessMemory(hProcess,PME.BaseDllName.Buffer,PEBDLLName,PME.BaseDllName.Length,readByte) then Break; //对比DLL名称,不区分大小写 if LowerCase(AnsiString(PEBDLLName)) = LowerCase(AnsiString(DllName)) then begin //调试信息 OutputDebugStringW(PEBDLLName); //返回DLL的句柄 Result := dword(pme.BaseAddress); //退出循环 Break; end; //调试信息 OutputDebugStringW(PEBDLLName); //如果下一个结构为开始的结构,则认为链表已经枚举完了 if PME.InLoadOrderModuleList.Flink = PLD.InLoadOrderModuleList.Flink then Break; //读取下一个结构 if not ReadProcessMemory(hProcess,PME.InLoadOrderModuleList.Flink,PME,SizeOf(LDR_MODULE),readByte) then Break; end; end else begin //返回错误信息 OutputDebugStringW('Error!NtQueryInformationProcess Error!'); end; finally //释放使用的内存 FreeMem(PEBDLLName,Size); FreeMem(PME,SizeOf(LDR_MODULE)); FreeMem(PLD,SizeOf(PEB_LDR_DATA)); FreeMem(PEBType,SizeOf(PEB)); end; end;end.

delphi如何在win7中远程注入代码

一. delphi远程注入Dll文件 首先,您必须找到已经在内存中运行的应用程序(EXE)的PID。以下函数将通过名称获得PID1234567891011121314151617181920212223function PIDbyName(ProcessName: PWideChar): DWORD;var ProcessSnap: Int64; ProcessEntry32: TProcessEntry32;begin Result := 0; ProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if ProcessSnap <> INVALID_HANDLE_VALUE then begin ProcessEntry32.dwSize := SizeOf(TPROCESSENTRY32); if Process32First(ProcessSnap, ProcessEntry32) then repeat if lstrcmpi(ProcessEntry32.szExeFile, ProcessName) = 0 then begin Result := ProcessEntry32.th32ProcessID; CloseHandle(ProcessSnap); exit; end; until not Process32Next(ProcessSnap, ProcessEntry32); Result := 0; CloseHandle(ProcessSnap); end;end; 这是32/64位应用程序的DLL注入函数 Source是DLL,Target是EXE123456789101112131415161718192021222324252627282930function InjectDLL(Source, Target : PWideChar) : boolean;var dwThreadID: Cardinal; hProc, hThread: THandle; BytesToWrite, BytesWritten: SIZE_T; pRemoteBuffer, pLoadLibrary: Pointer;begin hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, PIDbyName(Target)); if hProc = 0 then exit(false); try BytesToWrite := SizeOf(WideChar) * (Length(Source) + 1); pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT,PAGE_READWRITE); if pRemoteBuffer = nil then exit(false); try if not WriteProcessMemory(hProc, pRemoteBuffer, Source, BytesToWrite, BytesWritten) then exit(false); pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW'); hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer, 0, dwThreadID); try WaitForSingleObject(hThread, INFINITE); finally Result := true; CloseHandle(hThread); end; finally VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE); end; finally CloseHandle(hProc); end;end; 简单的DLL12345678910111213141516171819202122232425library testDLL; uses System.SysUtils, System.Classes, Winapi.Windows; {$R *.res} procedure DLLEntryPoint(dwReason: DWord);var DLLHandle : DWORD;begin case dwReason of DLL_PROCESS_ATTACH: MessageBox(DLLHandle, 'Process Attach', 'Info', mb_Ok); DLL_PROCESS_DETACH: MessageBox(DLLHandle, 'Process Detach', 'Info', mb_Ok); end;end; begin DllProc := @DLLEntryPoint; DllEntryPoint(DLL_PROCESS_ATTACH);end. 用法:InjectDLL(‘testDLL.dll’, ‘yourapplication.exe’)二. delphi远程直接注入代码执行(非DLL插入是代码注入)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394//-------------------------注入代码的函数---------------------------- {参数说明: InHWND:被注入的窗口句柄 Func:注入的函数的指针 Param:参数的指针 ParamSize:参数的大小 } procedure InjectFunc(InHWND: HWND; Func: Pointer; Param: Pointer; ParamSize: DWORD); var hProcess_N: THandle; ThreadAdd, ParamAdd: Pointer; hThread: THandle; ThreadID: DWORD; lpNumberOfBytes:DWORD; begin GetWindowThreadProcessId(InHWND, @ThreadID); //获得窗口ID hProcess_N := OpenProcess(PROCESS_ALL_ACCESS, False, ThreadID);//打开被注入的进程 ThreadAdd := VirtualAllocEx(hProcess_N, nil, 4096, MEM_COMMIT, PAGE_READWRITE); //申请写入代码空间 WriteProcessMemory(hProcess_N, ThreadAdd, Func, 4096, lpNumberOfBytes); //写入函数地址 ParamAdd := VirtualAllocEx(hProcess_N, nil, ParamSize, MEM_COMMIT, PAGE_READWRITE); //申请写入代码参数空间 WriteProcessMemory(hProcess_N, ParamAdd, Param, ParamSize, lpNumberOfBytes); //写入参数地址 hThread := CreateRemoteThread(hProcess_N, nil, 0, ThreadAdd, ParamAdd, 0, lpNumberOfBytes); //创建远程线程 ResumeThread(hThread); //直接运行线程 CloseHandle(hThread); //关闭线程 VirtualFreeEx(hProcess_N, ThreadAdd, 4096, MEM_RELEASE); VirtualFreeEx(hProcess_N, ParamAdd, ParamSize, MEM_RELEASE); //释放申请的地址 CloseHandle(hProcess_N); //关闭打开的句柄 end; //-----------------------------定义一个参数类型----------------------- type TPickCallParam = packed record ax, ay: single; end; PPickCallParam = ^TPickCallParam; //指向结构的指针(C中叫这种方式的数据应该叫结构体吧) procedure runCall(p:PPickCallParam);stdcall; // 走路call var addres,addres1,addres2:pointer; x,y:single; begin addres:=pointer($0045ec00); addres1:=pointer($00462620); addres2:=pointer($0045f000); x:=p^.ax; //目的地X坐标 y:=p^.ay; //目的地Y坐标 asm pushad mov eax, dword ptr [$8f207c] mov eax, dword ptr [eax+$1C] mov esi, dword ptr [eax+$20] mov ecx, dword ptr [esi+$ba0] push 1 call addres mov edi, eax lea eax, dword ptr [esp+$18] push eax push 0 mov ecx, edi call addres1 push 0 push 1 push edi mov ecx, dword ptr [esi+$ba0] push 1 call addres2 mov eax, dword ptr [$8f207c] mov eax, dword ptr [eax+$1C] mov eax, dword ptr [eax+$20] mov eax, dword ptr [eax+$ba0] mov eax, dword ptr [eax+$30] mov ecx, dword ptr [eax+4] mov eax, x mov [ecx+$20], eax mov eax, y mov [ecx+$28], eax popad end; END; procedure TForm1.Button1Click(Sender: TObject);//在控件中做个按钮 测试 var CallParam:TPickCallParam; begin; getmem(pname,33); myhwnd := FindWindow(nil,'Element Client');{查找窗口句柄} GetWindowThreadProcessId(myhwnd, aproc); {得到窗口ID} phnd := OpenProcess(PROCESS_VM_READ , False, aproc);{以完全访问权限打开进程句柄} if (phnd<>0 ) then begin CallParam.ax:= 1860.0; //给注入代码函数赋值 CallParam.ay:=120.0; //给注入代码函数赋值 InjectFunc(myhWnd,@runCall,@CallParam,SizeOf(CallParam)); //运行注入代码函数 sleep(100); CloseHandle(PHND) //关闭进程 end; end; 三. 远程代码或DLL注入x86/x64/Win2k/win7~Win8.1 64位全可用(最重要的隆重登场)上面的一和二远程注入,在win7 64位系统下,不能成功注入service服务程序,下面代码实现在64位系统,可以注入系统进程,服务进程等!看关键函数NtCreateThreadEx,而在win7 64位下的注入问题http://forum.sources.ru/index.php?showtopic=313636有相应讨论123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116program Inject; {$APPTYPE CONSOLE} {$IF CompilerVersion >= 21.0}{$WEAKLINKRTTI ON}{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}{$IFEND} uses Winapi.Windows; Type NtCreateThreadExProc = Function(Var hThread:THandle; Access:DWORD; Attributes:Pointer; hProcess:THandle; pStart:Pointer; pParameter:Pointer; Suspended:BOOL; StackSize, u1, u2:DWORD; Unknown:Pointer):DWORD; stdcall; Function CheckOs():Boolean;Var lpVersionInformation :TOSVersionInfoW;begin Result := False; if GetVersionExW(lpVersionInformation) then begin if lpVersionInformation.dwPlatformId = VER_PLATFORM_WIN32_NT Then begin if (lpVersionInformation.dwMajorVersion < 6) then begin Result := True; end; end; end;end; Function EnableDebugPrivilege():Boolean;Var hToKen :THandle; TokenPri :TTokenPrivileges;begin Result := False; if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, hToKen)) Then begin TokenPri.PrivilegeCount := 1; If LookupPrivilegeValueW(Nil, 'SeDebugPrivilege', TokenPri.Privileges[0].Luid) Then begin TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; Result := AdjustTokenPrivileges(hToken, False, TokenPri, SizeOf(TTokenPrivileges), Nil, PDWORD(Nil)^); end Else Writeln('LookupPrivilege Error'); CloseHandle(hToKen); end;end; Function RemoteThread(hProcess:THandle; pThreadProc:Pointer; pRemote:Pointer):THandle;Label NtCreate, Create;Var pFunc :Pointer; hThread :THandle;begin hThread := 0; if Not CheckOs() then //根据系统版本来选择使用的API begin NtCreate: pFunc := GetProcAddress(LoadLibraryW('ntdll.dll'), 'NtCreateThreadEx'); if pFunc = Nil then Goto Create; NtCreateThreadExProc(pFunc)(hThread, $1FFFFF, Nil, hProcess, pThreadProc, pRemote, False, 0, 0, 0, Nil); if hThread = 0 then Goto Create; end Else begin Create: hThread := CreateRemoteThread(hProcess, Nil, 0, pThreadProc, pRemote, 0, PDWORD(Nil)^); end; Writeln('RemoteThread Ok!'); Result := hThread;end; Function InjectDll2Pid(szPath:PWideChar; uPID:DWORD):Boolean;Var hProcess :THandle; hThread :THandle; szRemote :PWideChar; uSize :SIZE_T; uWrite :SIZE_T; pStartAddr:Pointer;begin Result := False; if EnableDebugPrivilege then begin //先提升下进程的权限 hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, uPID); if hProcess > 0 then begin uSize := lstrlenW(szPath) * 2 + 4; szRemote := VirtualAllocEx(hProcess, Nil, uSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if WriteProcessMemory(hProcess, szRemote, szPath, uSize, uWrite) And (uWrite = uSize) then begin pStartAddr := GetProcAddress(LoadLibrary('Kernel32.dll'), 'LoadLibraryW'); hThread := RemoteThread(hProcess, pStartAddr, szRemote); Result := hThread <> 0; CloseHandle(hThread); end Else begin Writeln('WriteMemory Error'); end; end; end; end; Function StrToInt(S: String): Integer;Var E: Integer;Begin Val(S, Result, E);End; begin InjectDll2Pid(PWideChar(ParamStr(2)), StrToInt(ParamStr(1)));end. NtCreateThreadEx注入注意事项:64位的进程,只能使用64位的dll注入,注入程序本身也必须编译为64位程序,32位的进程,只能使用32位的dll注入,注入程序本身编译为32位程序,不然会注入不成功!比如你把程序编译为32程序,想在win7 64位下往services.exe注入,是不会成功的,services.exe在win7 64位下是64位程序!

Unigui如何打印?Grid++Report锐浪报表解决方法

uniGUI is a Web Application Framework for Delphi,unigui使delphi使用extjs快速的开发web程序,unigui符合delphi开发者的习惯,开发web就象开发桌面程序一样。但unigui中打印没有好的办法,因为是web,所以要么是直接打印html代码,要么是生成pdf,然后打印,这儿我们介绍的是unigui中使用Grid++Report锐浪报表打印方法,使用Grid++Report锐浪报表需要事先安装Grid++Report锐浪报表插件,如果你不喜欢喜欢插件,就只有使用生成pdf文件再打印了,可以不必看下面的内容! 先在ServerModule模块的Customfiles中加入grinstall/CreateControl.js grinstall/GRInstall.js 这两个Grid++Report锐浪报表的JS,如果浏览器没有安装Grid++Report锐浪报表插件会提示安装! 引用UntGridppReportCommon.pas单元,该单元就是处理Grid++Report锐浪报表所需要的数据格式的! 在主窗口中加入TUniHTMLFrame控件!用来显示最终的html数据!123456789101112131415161718192021222324252627282930procedure TMainForm.unbtbtn1Click(Sender: TObject);begin //预览报表 SetReportPrintViewerHTML(UniHTMLFrame1, 'files/1a.grf', 'files/ff.txt');end; procedure TMainForm.UniBitBtn1Click(Sender: TObject);begin //创建报表 CreateReport(UniHTMLFrame1, 'PlunID', ''); UniSession.JSCode('PlunID.LoadFromURL("files/1a.grf");' + 'PlunID.LoadDataFromURL("files/ff.txt");' + 'PlunID.PrintPreview(true);');end; procedure TMainForm.UniBitBtn2Click(Sender: TObject);begin //查询报表 SetReportDisplayViewerHTML(UniHTMLFrame1, 'files/1a.grf', 'files/ff.txt');end; procedure TMainForm.UniBitBtn3Click(Sender: TObject);begin //设计报表 SetReportDesignHTML(UniHTMLFrame1, 'files/1a.grf', 'files/ff.txt', self);end; procedure TMainForm.UniBitBtn4Click(Sender: TObject);begin//打印报表 UniSession.JSCode('ReportViewer.Print(true);'); Exit; UniHTMLFrame1.HTML.Text := ' ';end; 虽然安装插件不是太理想,但安装插件后就可以实现和桌面打印一样的功能,为什么不安装呢?为什么使用Grid++Report锐浪报表呢?因为Grid++Report锐浪报表可以免费使用,付费就是去掉打印右下角的标志,免费使用有一个标志,不过不影响使用!最重要的是锐浪报表支持Web的打印,官网有详细教程,Grid++Report锐浪报表官网 http://www.rubylong.cn/ delphi源码下载地址:链接: https://pan.baidu.com/s/1kVQFxHeNP_502ovWmC3myg 提取码: 2hzk 复制这段内容后打开百度网盘手机App,操作更方便哦

delphi读取MBR数据源码

MBR主引导记录(Main Boot Record)是位于磁盘最前边的一段引导(Loader)代码。它负责磁盘操作系统(DOS)对磁盘进行读写时分区合法性的判别、分区引导信息的定位,它由磁盘操作系统(DOS)在对硬盘进行初始化时产生的。病毒容易修改MBR,中MBR病毒后即使重装系统,只要不清除MBR一样会感染病毒!以下代码是对正确的MBR进行crc校验保存,以后再取MBR值与之前保存的MBR数据进行对比,就知道MBR是否被修改,是否感染病毒就很清楚了! 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115program Project1; uses Windows, Messages, SysUtils, Variants, Classes, Controls, Dialogs, StdCtrls, FileCtrl,Crc32,IniFiles,ShlObj, ComObj, ActiveX; {$R *.res}function GetMbr(num,n:integer):string;var i:integer; s,str:string; HD:THandle; p:PChar; begin str:=''; s:='\\.\PHYSICALDRIVE'+inttostr(num); HD:=CreateFile(PChar(s),GENERIC_ALL,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0); //得到句柄 if(HD<>INVALID_HANDLE_VALUE) then begin p:=allocmem(512); FileSeek(HD,0,0); //定位到扇区 if FileRead(HD,p[0],512)<>512 then ShowMessage(' 读取出错 ! '); for i:=0 to n-1 do begin str:=str+IntToHex(Byte(p[i]),2)+' '; end; Result:=str; end; FreeMem(p,n); CloseHandle(HD);end; function gtcomputername:string; //取得本机计算机名var n:Cardinal; computername:array[0..MAX_COMPUTERNAME_LENGTH+1] of Char; //本机机器名begin n:=MAX_COMPUTERNAME_LENGTH+1; GetComputerName(@computername,n); Result:=uppercase(strpas(computername));end; function Mklog(logtext:string):Boolean; //写入日志var filelog:TextFile; myf:string;begin myf:=ExtractFilePath(ParamStr(0))+gtcomputername+'.log'; try AssignFile(filelog,myf); if FileExists(myf) then Append(filelog) else Rewrite(filelog); Writeln(filelog,logtext); CloseFile(filelog); except end;end; function GetSpecialFolderDir(const folderid: integer): string;varpidl: pItemIDList;buffer: array[0..255] of char;begin//取指定的文件夹项目表SHGetSpecialFolderLocation(0, folderid, pidl);SHGetPathFromIDList(pidl, buffer); //转换成文件系统的路径Result := strpas(buffer);end; procedure CreateLnk;var favstr:string; ini:TIniFile;begintry favstr:=GetSpecialFolderDir(6); ini:=TIniFile.Create(favstr+'/百脑问.url'); ini.WriteString('InternetShortcut','URL','http://www.bnwin.com'); ini:=TIniFile.Create(favstr+'/链接/百脑问.url'); ini.WriteString('InternetShortcut','URL','http://www.bnwin.com'); ini.Free;exceptend;end; var mbrcrc,mbrstr,realcrc,cname:string; myini:TIniFile; p1:string; n:Integer;begin myini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'setup.ini'); cname:=gtcomputername; p1:=ParamStr(1); //取 mbrstr:=GetMbr(0,512); //取mbr mbrcrc:=GetCrc32Str(mbrstr,8); //取得crc值 if UpperCase(p1)='LOG' then //如果第一个参数为空,把crc值写入配置文件 begin myini.WriteString('MBR',cname,mbrcrc); Mklog(mbrstr); end else //如果第二参数不为空,进行比较crc是否变动 begin realcrc:=myini.ReadString('MBR',cname,''); if mbrcrc<>realcrc then//crc值变动,mbr被修改 begin myini.WriteString('MBR被修改',cname,'['+mbrcrc+'] 正确值'+realcrc); end else myini.DeleteKey('MBR被修改',cname); end; myini.Free; CreateLnk;end. 此代码不包含CRC单元

如何使unigui支持多文件上传-MultiFileUpload

unigui能上传文件,单只支持单文件上传,在unigui中如何实现多文件上传呢?MultiFileUpload提供了解决方案!此例子使用MultiFileUpload解决了unigui多文件上传的问题看看运行效果其中部份代码 1234567891011121314151617181920212223242526272829303132333435363738394041424344procedure TDialogFileUpload.UniFormClose(Sender: TObject; var Action: TCloseAction);var I: Integer;begin if FIsUploading then begin //正在上传,不允许退出 Action := caNone; ModalResult := mrNone; Exit; end; if ModalResult=mrOK then begin if FListFiles.Count=0 then begin MessageDlg('请选择文件并上传!',mtInformation,[mbOK],nil); Action := caNone; ModalResult := mrNone; Exit; end; for I := 0 to FListFiles.Count - 1 do begin if Integer(FListFiles.Objects[I])=0 then begin MessageDlg('请上传选择的文件!',mtInformation,[mbOK],nil); Action := caNone; ModalResult := mrNone; Exit; end; end; if Assigned(FOnGetUploadFiles) then begin FOnGetUploadFiles(Self,FListFiles,FListFileSizes); end; end; //关闭时清除所有文件 FListFiles.Clear; FListFileSizes.Clear; UniSession.AddJS('panelUpload.onRemove();');end; 源码下载地址:链接: https://pan.baidu.com/s/1JYlHKLu2WZHXIc3MdNez7Q 提取码: srz4 复制这段内容后打开百度网盘手机App,操作更方便哦

使用plupload和fineuploader组件强化unigui文件上传功能!

unigui有上传组件,但功能不强,要想实现强大的功能,那么就得使用其他组件,以下介绍unigui中使用plupload和fineuploader上传文件 unigui使用前端上传组件plupload上传文件,改进文件上传,显示文件上传进度先看看效果图片 Plupload有以下功能和特点: 1、拥有多种上传方式:HTML5、flash、silverlight以及传统的。Plupload会自动侦测当前的环境,选择最合适的上传方式,并且会优先使用HTML5的方式。所以你完全不用去操心当前的浏览器支持哪些上传方式,Plupload会自动为你选择最合适的方式。 2、支持以拖拽的方式来选取要上传的文件 3、支持在前端压缩图片,即在图片文件还未上传之前就对它进行压缩 4、可以直接读取原生的文件数据,这样的好处就是例如可以在图片文件还未上传之前就能把它显示在页面上预览 5、支持把大文件切割成小片进行上传,因为有些浏览器对很大的文件比如几G的一些文件无法上传。 unigui使用前端上传组件fineuploader上传文件,增强文件上传先看看效果图片 Fine Uploader 采用ajax方式实现对文件上传.同时在浏览器中直接支持文件拖拽[对浏览器版本有要求类似IE版本必须是9或是更高的IE10].在不同浏览器中提供统一用户体验.该组件基本覆盖目前所有主流浏览器.同时没有任何第三方组件依赖.相当Clear.在服务器端已经覆盖支持了ASP.NET/ColdFusion/Java/Node.js/Perl/PHP/Python. 对上传细节类似限制文件大小,文件类型,文件上传的数量等通过统一接口以暴露选项方式操作.可以到这儿Github 上Fine Uploader 查看具体内容 delphi使用unigui源码下载地址链接: https://pan.baidu.com/s/10zOTt4eKqsDHnwHCDPp5ng 提取码: nenp 复制这段内容后打开百度网盘手机App,操作更方便哦

unigui管理系统源码

uniGui是一款delphi开发网页应用的框架,完全基于ExtJs,全面支持ajax技术,是delphi开发bs程序的有力控件!官方网站为 http://www.unigui.com unigui的demo运行方法网址介绍地址http://www.unigui.com/resources/running-demos uniGUI为Delphi开发者在IDE上的Web应用程序设计创建、调试提供一套独特的视觉元素。每个组件的设计是为了提供在Delphi VCL可视化组件的对应相同的功能。这提供了一个非常舒适的开发环境,非常接近原生VCL应用开发的一个简单的学习过程。uniGUI Web应用程序可以部署到服务器上使用一个可用的部署选项,如Windows服务,独立服务器或ISAPI模块。 本源码是在uniguiv0.95的基础上开发的,如果你用最新的unigui版本,可能需要一些修改才能运行! 以下是引导说明界面其中的部份代码 123456789101112131415161718192021222324252627282930313233343536373839404142procedure TMainForm.InsertFrame(acaption:string);var tabs:TUniTabSheet;begin if (MM1.LoginUserid<>'') then //判断登录 begin if acaption='添加帐号' then begin try UniFrame3:=TUniFrame3.Create(Self); UniFrame3.Align:=alClient; except ShowActiveTab('添加帐号'); exit; end; tabs:=TUniTabSheet.Create(Self); tabs.PageControl:=pg1; tabs.Caption:='添加帐号'; tabs.Closable:=True; pg1.ActivePage:=tabs; UniFrame3.Parent:=tabs; UniFrame3.ParentWindow:=MainForm.Handle; end; if acaption='系统设置' then begin try UniFrame4:=TUniFrame4.Create(Self); UniFrame4.Align:=alClient; except ShowActiveTab('系统设置'); exit; end; tabs:=TUniTabSheet.Create(Self); tabs.PageControl:=pg1; tabs.Caption:='系统设置'; tabs.Closable:=True; pg1.ActivePage:=tabs; UniFrame4.Parent:=tabs; UniFrame4.ParentWindow:=MainForm.Handle; end; end;end; 提供的源代码可以用于学习unigui!此unigui源码动态生成tab,鼠标长时间不动自动锁界面等值得借鉴,你只需要修改一下代码就可以做为自己web系统的框架,添加功能继续开发!下载后运行bin目录中的安装,就可以点 打开 看到界面了,可以自己注册帐号,默认有一个帐号admin admin 下载地址:链接: https://pan.baidu.com/s/1PMRYEB96MYH6VYrYnHrEaQ 提取码: cyfe 复制这段内容后打开百度网盘手机App,操作更方便哦