Delphi 如何在内存中设置/检测/删除其他进程可以看到的全局标志?
在Delphi XE2中,如何在内存中设置一个特定的全局标志,该标志可以被其他进程看到,并且在创建全局标志的进程终止时不会被删除。例如:Delphi 如何在内存中设置/检测/删除其他进程可以看到的全局标志?,delphi,delphi-xe2,Delphi,Delphi Xe2,在Delphi XE2中,如何在内存中设置一个特定的全局标志,该标志可以被其他进程看到,并且在创建全局标志的进程终止时不会被删除。例如: if GlobalAddAtom('{B244A213-72EC-47BF-814B-2E7608F55C50}') <> 0 then MessageDialog('GlobalFlag has been created'); 1) 过程A: if CreateGlobalFlag('{B244A213-72EC-47BF-814B-2E7
if GlobalAddAtom('{B244A213-72EC-47BF-814B-2E7608F55C50}') <> 0 then
MessageDialog('GlobalFlag has been created');
1) 过程A:
if CreateGlobalFlag('{B244A213-72EC-47BF-814B-2E7608F55C50}') then
MessageDialog('GlobalFlag has been created');
2) ProcessA终止
3) 过程B:
boolGlobalFlagExists := IsGlobalFlagSet('{B244A213-72EC-47BF-814B-2E7608F55C50}');
if boolGlobalFlagExists then
begin
if RemoveGlobalFlag('{B244A213-72EC-47BF-814B-2E7608F55C50}') then
MessageDialog('GlobalFlag has been removed');
end;
不知道上述GUID的其他进程应该无法检测此全局标志
如何实现这样的功能
EDIT201406231757:如果可能,全局标志应存在于内存中。
如果可能的话,该标志应一直有效,直到Windows关闭。
如果可能,全局标志应为每台机器(而不是每用户)。
全局标志应在关机时消失。
如果可能的话,全局标志应该是秘密的。您可以使用全局原子将内存中的标志保留到进程的生存期之后 : 只要字符串atom的引用计数大于零,即使在将其放入表中的应用程序终止后,字符串atom的原子名仍保留在全局atom表中 例如:
if GlobalAddAtom('{B244A213-72EC-47BF-814B-2E7608F55C50}') <> 0 then
MessageDialog('GlobalFlag has been created');
如果GlobalAddAtom({B244A213-72EC-47BF-814B-2E7608F55C50})为0,则
MessageDialog(“已创建GlobalFlag”);
var
GlobalFlag:原子;
开始
GlobalFlag:=GlobalFindAtom(“{B244A213-72EC-47BF-814B-2E7608F55C50}”);
如果GlobalFlag为0,则
开始
SetLastError(0);
GlobalDeleteAtom(GlobalFlag);
如果GetLastError()=0,则
MessageDialog('GlobalFlag已删除');
结束;
请记住,全局原子表是一个有限的资源。它一次只能容纳少于16K个原子,这些原子用于其他全局资源,如注册的剪贴板格式。所以要少用原子
此外,不可预见的情况,如资源管理器/会话崩溃,可能会擦除全局atom表,从而丢失您的标志。我之前玩过atoms,注意到问题得到了回答:
program TestAtoms;
{$APPTYPE CONSOLE}
uses
Windows;
const
AtomName = 'bla-bla-bla-bla-bla-bla-bla';
var
AtomValue: TAtom;
procedure Test;
begin
AtomValue:= GlobalFindAtom(PChar(AtomName));
if AtomValue = 0 then begin
Writeln('Atom not found, creating');
AtomValue:= GlobalAddAtom(PChar(AtomName));
if AtomValue <> 0 then
Writeln('Atom created, ', AtomValue)
else
Writeln('Atom create failed !!!');
end
else begin
Writeln('Atom found, deleting');
SetLastError(ERROR_SUCCESS);
GlobalDeleteAtom(AtomValue);
if GetLastError = ERROR_SUCCESS then
Writeln('Atom deleted')
else
Writeln('Atom delete failed !!!');
end;
end;
begin
Test;
Readln;
end.
与其使用Atom表,不如使用易失性注册表项。有关详细信息,请参阅文档。
REG\u选项\u VOLATILE
将创建一个仅在内存中维护的项,并在卸载相关注册表配置单元时丢弃该项
因此,如果使用RegCreateKeyEx
在HKEY\U LOCAL\U机器
键中创建一个REG\u选项
键,该键将一直保留到机器关闭
如果确实需要对内容保密,可以保护注册表项,以确保只有某些用户或组可以读取其内容
这应该满足您列出的所有要求。在公用文件夹中创建一个具有此名称的空文件;或具有此名称的注册表项;很多解决方案都是可能的。你想让国旗挂在哪里?它的一生是什么?永远。直到另一个进程关闭。是每用户还是每台机器?当用户注销时它会死掉吗?关闭?你想把国旗放在哪里?在内存中,如果可能的话它的一生是什么?如果可能的话,直到Windows关闭是每用户还是每台机器?每台机器,如果可能的话。它在关机时死亡。@user246408全局标志应该是机密的。可以检测到公用文件夹中的文件。它不是机密文件。如果其他程序可以读取,那么其他程序也可以读取。如果让进程A在进程B启动之前终止,我看不出您将如何将其保存在内存中和磁盘之外。也许您需要进程C一直运行并充当中间人。您是否有修改设计的余地,或者您是否已经决定修改,并且无法灵活地进行更改。非常感谢Remy Lebeau和user246408提供了此ATOM解决方案!!谢谢你的更新信息。但是,攻击者可以从匿名GUID中获得哪些信息?他可以追溯到我的应用程序吗?@user我们很难在不知道您的要求的情况下就安全性向您提供建议。@DavidHeffernan我没有让user246408向我提供一般性建议,而是专门问他是否有人可以从Atom项中获得Atom项的创建者。
procedure ScanAtomTable;
var
nAtom: TAtom;
Buffer: array[0..1023] of Char;
Size: Cardinal;
S: string;
begin
nAtom:= $C000;
repeat
Size:= GlobalGetAtomName(nAtom, @Buffer, 1024);
if Size > 0 then begin
S:= PChar(@Buffer);
Writeln(S);
end;
Inc(nAtom);
until nAtom = 0;
end;