GetModuleFileNameEx of Thread ID? - delphi

I am trying to get the file path of a thread id.
I was hoping that this will work..but it doesn't
NtOpenThread(#hProc, THREAD_ALL_ACCESS, #ObjAttr, #ClientID) ;
pBuf := AllocMem(MAX_PATH);
GetModuleFileNameEx(hProc, 0, pBuf, MAX_PATH);
Any idea how it is done ?

GetModuleFileNameEx requires a process handle, not a thread handle, which explains why your code doesn't work. There are two main ways to get a process handle. The first is from CreateProcess, but that's no good unless you're the one starting the process, and if you're doing that, you don't need GetModuleFileNameEx in the first place.
The second way to get a process handle is from OpenProcess. That requires a process ID. You can get a thread's process ID with GetProcessIdOfThread, which takes a thread handle. You already know how to get a thread handle from a thread ID with NtOpenThread, although the usual function is plain old OpenThread.
If your Windows version doesn't support GetProcessIdOfThread, you can go another route with Thread32First and Thread32Next. Call CreateToolhelp32Snapshot, and then walk the thread list. Look for an entry where th32ThreadID equals the thread ID you're interested in. When you find it, th32OwnerProcessID will hold the corresponding process ID. Call OpenProcess and proceed as above.
Also note that you should not have to request ALL_ACCESS permissions when opening threads or processes, and attempting to do so may cause your program to fail. Request only the minimum permissions you need to accomplish your task. Requesting all access is the lazy way when you don't know what you need, but it will only work when your program already has administrative privileges. Instead, spend the time to figure out what permissions you really need.

Related

XGrabPointer poll till next event or pipe

I was trying to write a mouse event listener. This was my approach, can you please tell me if this will work before I start writing it. I'm writing it in ctypes, so if I ctype it all (couple days) then find out it doesnt work its a loss of time.
My goal is, that I should be able to cancel the poll via a pipe. This was my approach:
In another thread call XThreadsInit
Open XDisplay display
XGrabPointer to display
get file descriptor ConnectionNumber(display)
connect to pipe that was made on main thread
Do a pselect with no timeout timeout is set to null on pipe and fd from 4
Is this right approach?
Thanks
If you are using threads you are sharing variables between threads. It would be much simpler to use a global variable that is set when the poll must be aborted, then in your watch thread create a tight loop that checks for that variable and use a short timeout in pselect(). This may introduce a short delay but if you keep the timeout short (say, 100 ms) it would be hardly noticable and still efficient.

Reference vs pid?

I'm not entirely sure the differences between the PID and Reference and when to use which.
If I were to spawn a new process with spawn/1 pid. I can kill it with the PID no? Why would I need a reference?
Likewise I see monitor/1 receiving a message with a ref and pid number.
Thanks!
Pid is process identifier. You can get one when you create new process with spawn, or you can get Pid of yourself with self(). It allows you to interact with given process. Especially send messages to it by Pid ! Message. And some other stuff, like killing it explicitly (should not do) or obtaining some process information with erlang:process_info.
And you can create relations between process with erlang:link(Pid) and erlang:monitor(process, Pid) (that's between Pid process, and process execution this function). In short, it gives you "notifications" when another process dies.
Reference is just almost unique value (of different type). One might say, that it gives you some reference to here and now, which you could recognize later. For example, if we are sending a message to another process, and we expect a response, we would like to make sure, that the message we will receive is associated to our request, and not just any message from someone else. The easiest way to do it is to tag the message with a unique value, and wait until a response with exactly the same tag.
Tag = make_ref(),
Pid ! {Tag, Message},
receive
{Tag, Response} ->
....
In this code, with use of pattern matching, we make sure that (we wait in receive until) Response is exactly for the Message we sent. No matter other messages from other processes. This is the most common use of reference you can encounter.
And now back to monitor. When calling Ref = monitor(process, Pid) we make this special connection with Pid process. Ref that is returned is just some unique reference, that we could use to demonitor this process. That is all.
One might ask, if we are able to create monitor with Pid, why do we need Ref for demonitoring? Couldn't we just use Pid again. In theory we could, but monitors are implemented in such a way, that multiple monitors could be established between two same processes. So when demonitoring, we have to remove only one of such connections. It is done in this way to make monitoring more transparent. If you have library of function that's creating and removing one monitor, you would not like to interfere with other libraries and functions and monitors they might be using.
According this page:
References are erlang objects with exactly two properties:
They can be created by a program (using make_ref/0), and,
They can be compared for equality.
You should use it ever you need to bind an unique identifier to some "object". Any time you could generate new one using erlang:make_ref/0. Documentation says:
make_ref() -> reference()
Returns an almost unique reference.
The returned reference will re-occur after approximately 2^82 calls;
therefore it is unique enough for practical purposes.
When you call erlang:monitor/2 function, it returns you reference to give you availability to cancel monitor (erlang:demonitor/1 function). This reference only identifies certain call of erlang:monitor/1. If you need operate with process (kill it, for example), you still have to use process pid.
Likewise I see monitor/1 receiving a message with a ref and pid number.
Yep, monitor sends messages like {'DOWN', Ref, process, Pid, Reason}. What to use (pid or ref) is only depends on your application logic, but (IMO) in most usual cases, there is no matter what to use.

How to check if queue with auto-generated name (amq.gen-*) exists?

In case of non-generated names it's enough to call #'queue.declare' to get newly created queue or existing one with given name. However, when using auto-generated names (beginning with amq.gen- prefix) it's not as trivial. First of all, amq. is restricted prefix, so there is no way to call #'queue.declare'{queue=<<"amq.gen-xxx">>}.
I also tried to play with passive=true option and although I may pass restricted name, I get an exit error when queue does not exists. Following is error report:
** Handler sse_handler terminating in init/3
for the reason exit:{{shutdown,
{server_initiated_close,404,
<<"NOT_FOUND - no queue 'amq.gen-wzPK0nIBPzr-dwtZ5Jy58V' in vhost '/'">>}},
{gen_server,call,
[<0.62.0>,
{call,
{'queue.declare',0,
<<"amq.gen-wzPK0nIBPzr-dwtZ5Jy58V">>,
true,false,false,false,false,[]},
none,<0.269.0>},
infinity]}}
Is there any way to solve this problem?
EDIT: Here is a short story behind this question. Disclaimer: I'm erlang newbie, so maybe there is better way to make it working :)
I have a gen_server based application holding SSE (server-side events) connections with web browsers. Each connection is bound to rabbitmq queue. SSE connection when broken, automatically tries to reconnect after given timeout - this is something that web browser supports out of the box. To reuse previously created queue I'm trying to check if queue of given name (taken from request cookie) already exists. It's all done in init callback.
You can declare a queue with the prefix amq. if the queue already exists. You would get Declare-Ok if the queue exists or access-refused if not. (My question is why would you, though? ;)
Furthermore, you can use the passive option to check if it already exists. According to AMQP reference the server treats it as not-found error if the queue doesn't exist. In order to catch this in your Erlang client you could try something around the lines of this:
try
%% declare queue with passive=true
queue_exists
catch exit:{{shutdown, {server_initiated_close,404,_},_,_} ->
queue_does_not_exist
end

How to get the Process Environment Block (PEB) from extern process?

I want to get the PEB from the "notepad.exe" process. Does someone know how to do it?
I tried the GetModuleHandle API, but it doesn't return a valid pointer (it return zero every time) because I have to be the caller process of that module.
For that reason, I want to know how to get it to work with EnumProcessModules or CreateToolhelp32Snapshot.
Matt Pietrek described how to do that in a 1994 Under the Hood column. It was about how to get the environment variables of another process, where the first step is to get a pointer to the PEB. To do that, he says, call NtQueryInformationProcess. The PROCESS_BASIC_INFORMATION structure it fills contains the base address of the PEB structure. (You'll need to use ReadProcessMemory to read it since the address will be in the context of the external process's address space, not yours.)
To call NtQueryInformationProcess, you'll need a handle to the process. If you started the process yourself (by calling CreateProcess), then you already have a handle. Otherwise, you'll need to find the process ID and then call OpenProcess. To get the process ID, search for the process you want with EnumProcesses or Process32First/Process32Next. (I prefer the latter because it provides more information with less work.)

How to track down access violation "at address 00000000"

I know how to create a .map file to track down access violation errors when the error message includes an actual address.
But what if the error message says
Access violation at address 00000000. Read of address 00000000.
Where do I start looking for the cause of this problem... ?
The accepted answer does not tell the entire story.
Yes, whenever you see zeros, a NULL pointer is involved. That is because NULL is by definition zero. So calling zero NULL may not be saying much.
What is interesting about the message you get is the fact that NULL is mentioned twice. In fact, the message you report looks a little bit like the messages Windows-brand operating systems show the user.
The message says the address NULL tried to read NULL. So what does that mean? Specifically, how does an address read itself?
We typically think of the instructions at an address reading and writing from memory at certain addresses. Knowing that allows us to parse the error message. The message is trying to articulate that the instruction at address NULL tried to read NULL.
Of course, there is no instruction at address NULL, that is why we think of NULL as special in our code. But every instruction can be thought of as commencing with the attempt to read itself. If the CPUs EIP register is at address NULL, then the CPU will attempt to read the opcode for an instruction from address 0x00000000 (NULL). This attempt to read NULL will fail, and generate the message you have received.
In the debugger, notice that EIP equals 0x00000000 when you receive this message. This confirms the description I have given you.
The question then becomes, "why does my program attempt to execute the NULL address." There are three possibilities which spring to mind:
You have attempt to make a function call via a function pointer which you have declared, assigned to NULL, never initialized otherwise, and are dereferencing.
Similarly, you may be calling an "abstract" C++ method which has a NULL entry in the object's vtable. These are created in your code with the syntax virtual function_name()=0.
In your code, a stack buffer has been overflowed while writing zeros. The zeros have been written beyond the end of the stack buffer, over the preserved return address. When the function later executes its ret instruction, the value 0x00000000 (NULL) is loaded from the overwritten memory spot. This type of error, stack overflow, is the eponym of our forum.
Since you mention that you are calling a third-party library, I will point out that it may be a situation of the library expecting you to provide a non-NULL function pointer as input to some API. These are sometimes known as "call back" functions.
You will have to use the debugger to narrow down the cause of your problem further, but the above possiblities should help you solve the riddle.
An access violation at anywhere near adress '00000000' indicates a null pointer access. You're using something before it's ever been created, most likely, or after it's been FreeAndNil()'d.
A lot of times this is caused by accessing a component in the wrong place during form creation, or by having your main form try and access something in a datamodule that hasn't been created yet.
MadExcept makes it pretty easy to track these things down, and is free for non-commercial use. (Actually, a commercial use license is pretty inexpensive as well, and well worth the money.)
You start looking near that code that you know ran, and you stop looking when you reach the code you know didn't run.
What you're looking for is probably some place where your program calls a function through a function pointer, but that pointer is null.
It's also possible you have stack corruption. You might have overwritten a function's return address with zero, and the exception occurs at the end of the function. Check for possible buffer overflows, and if you are calling any DLL functions, make sure you used the right calling convention and parameter count.
This isn't an ordinary case of using a null pointer, like an unassigned object reference or PChar. In those cases, you'll have a non-zero "at address x" value. Since the instruction occurred at address zero, you know the CPU's instruction pointer was not pointing at any valid instruction. That's why the debugger can't show you which line of code caused the problem — there is no line of code. You need to find it by finding the code that lead up to the place where the CPU jumped to the invalid address.
The call stack might still be intact, which should at least get you pretty close to your goal. If you have stack corruption, though, you might not be able to trust the call stack.
If you get 'Access violation at address 00000000.', you are calling a function pointer that hasn't been assigned - possibly an event handler or a callback function.
for example
type
TTest = class(TForm);
protected
procedure DoCustomEvent;
public
property OnCustomEvent : TNotifyEvent read FOnCustomEvent write FOnCustomEvent;
end;
procedure TTest.DoCustomEvent;
begin
FOnCustomEvent(Self);
end;
Instead of
procedure TTest.DoCustomEvent;
begin
if Assigned(FOnCustomEvent) then // need to check event handler is assigned!
FOnCustomEvent(Self);
end;
If the error is in a third party component, and you can track the offending code down, use an empty event handler to prevent the AV.
When I've stumbled upon this problem I usually start looking at the places where I FreeAndNil() or just xxx := NIL; variables and the code after that.
When nothing else has helped I've added a Log() function to output messages from various suspect places during execution, and then later looked at that log to trace where in the code the access violation comes.
There are ofcourse many more elegant solutions available for tracing these violations, but if you do not have them at your disposal the old-fashioned trial & error method works fine.
It's probably because you are directly or indirectly through a library call accessing a NULL pointer. In this particular case, it looks like you've jumped to a NULL address, which is a b bit hairier.
In my experience, the easiest way to track these down are to run it with a debugger, and dump a stack trace.
Alternatively, you can do it "by hand" and add lots of logging until you can track down exactly which function (and possibly LOC) this violation occurred in.
Take a look at Stack Tracer, which might help you improve your debugging.
Use MadExcept. Or JclDebug.
I will second madExcept and similar tools, like Eurekalog, but I think you can come a good way with FastMM also. With full debugmode enabled, it should give you some clues of whats wrong.
Anyway, even though Delphi uses FastMM as default, it's worth getting the full FastMM for it's additional control over logging.
Here is a real quick temporary fix, at least until you reboot again but it will get rid of a persistent access. I had installed a program that works fine but for some reason, there is a point that did not install correctly in the right file. So when it cannot access the file, it pops up the access denied but instead of just one, it keeps trying to start it up so even searching for the location to stop it permanently, it will continue to pop up more and more and more every 3 seconds. To stop that from happening at least temporarily, do the following...
Ctl+Alt+Del
Open your Task Manager
Note down the name of the program that's requesting access (you may see it in your application's tab)
Click on your Processes tab
Scroll through until you find the Process matching the program name and click on it
Click End Process
That will prevent the window from persistently popping up, at least until you reboot. I know that does not solve the problem but like anything, there is a process of elimination and this step here will at least make it a little less annoying.

Resources