Detecting debuggers

Let’s assume that we’re all using an NT based OS (2k, XP, 2003). It’s a simple matter to detect that you’re being run unde a debugger – simply isue an IsDebuggerPresent call. Heck, you could even put it into a thread that intermittently polls and reacts (in)appropriately.
Of course, I’m not one for polling. Never have been. I just consider it ‘lower class’ to do something like that. This is of course why I like the next trick for detecting the arrival of a debugger.
what happens is that an external thread attaches and executed the ‘DbgUiRemoteBreakin’ function; which at some point issues an ‘DbgBreakPoint’, which of all things contains an int3 and a return statement (this is a kick the debugger operation).
Detecting the debugger consists of rewriting the function implementation.
What we want to do is invoke our function (fun) when a debugger attaches. The following code does just that, and as a result of the attachment of the process simply spits out a message and terminates.

#include <windows.h>
#include <stdio.h>
HANDLE wh;
void
message(void)
{
SetEvent(wh);
ExitThread(0);
}
int
main(int argc, char **argv)
{
unsigned char *abki;
HMODULE dlh;
wh = CreateEvent(NULL, FALSE, FALSE, NULL);
dlh = GetModuleHandle("ntdll.dll");
abki = (void *)GetProcAddress(dlh, "DbgUiRemoteBreakin");
if (abki != NULL) {
DWORD olp;
if (VirtualProtect(abki, 20, PAGE_EXECUTE_READWRITE, &olp)) {
*abki++ = 0xb8; // Mov EAX,
*(DWORD *)abki = (DWORD)message;
abki+=4;
*(WORD *)abki = 0xd0ff; // call EAX
} else {
printf("Page Protection Failed\n");
return (1);
}
}
WaitForSingleObject(wh, INFINITE);
printf("Debugger\n");
return (0);
}

This is the beginning of something bigger.

Assembly language, functions and misoriented parameters

I had a minor complaint some time back about the lack of consistency amongst the various windows APIs, they seemed to be written by people who chose one mechanism one day, and another the other day. The reality is that in such a large company as Microsoft, the different groups were consistent amongst themselves, the problem was that they were not consistent amongst each other.
This brings me to the rant du jour. When one finds oneself reading/writing assembly language, the code is platform consistent. For example on x86 the format is: operator parameters,destination. So, mov 0xffffffff, %eax means put the value 0xffffffff into the register eax. On Sparc the parameter and destinations are reversed so mov %l0,0x110011 means put the value 0x110011 into the register l0. It’s quite easy to see one from the other because you are aware of what platform you are on. Sun, for reasons best known to themselves reversed the order of the parameters – probably to make them more like the Solaris ‘native’ format and easier for their developers to follow.
All very fine and well, Sun are entitled to confuse native x86 developers all they want, and besides which, because of the consistency, it is a really easy switch.
My mini bugbear is of course, the bcopy function. It performs a block copy from a source to a destination. It’s part of libc, it’s simple, it’s easy to use, the only problem is that it is in the reverse order from all the string routines (dest, source), memmove (dest, src). If you look up the definition of bcopy it generally asserts that it is implemented in terms of memmove, and if you look at most implementations you find that bcopy just swaps the in and out parameters and then invokes memmove (I believe the exception is sparc, where this is the opposite). This is why bcopy is officially off my list of functions to use. It’s simply the one lone voice of dissent amongst all the consistency that libc affords.
Who made bcopy then?

journalspace premium services

Dermot has a mini-rant about this on his blog. It turns out that in order to do most anything useful on journalspace you need to pay for it. For example exporting RSS2.0 feeds is a premium service, which makes allowing rss readers access to your site (last updated pings, for example) costs you money. Being able to post from external applications (via XML-RPC) is another premium service, making cross blog synchronization difficult.
I suppose that is the price of using a free service.

still on the CSI – gotta love the grissom

More ‘extreme scenes’, but with a shiny happy ending. I think I need to sit down with about 4 days worth of the show to get it out of my system – just like I did with Kit Kat’s. I can’t eat one anymore without thinking – damn, but this is tastless crap. I’m currently avoiding going through the process with the Tesco continental thins. Yummy, but I’m careful about it.
Donal! Where can I buy the booze! It’s all good; honest!

The angst – the multi-step ADO operation tale continues

I thought I had it, but I didn’t. I still can’t find out the reason. Currently, after each post I re-read the table by closing and opening it. The table is a small, local, temporary table for recording information before posting it to the real database so I don’t really care that the exception is triggered.
Now, I’m getting DbgBreakPoint exceptions. This was in a simple showmodal call, so I have no idea why it’s there. Apparently it might have something to do with opening the table concerned.

At least one cause of ‘multi-step ADO operation generated errors’

I was experiencing this occasionally when implementing the delete functionality for a browse window. It turns out that I was not positioned on a record, but instead was either before first or after the last record. Simple problem, really but a bit of a pain to discover the reason as the error isn’t really informative.
The solution was to do move to either the first or last record. Thanks to the magic of the ‘meta bof/eof records’. I have to use the description loosely, as they definitely ain’t records and the correctness police would be rapping my knuckles for such a statement.
Discovering the solution was not helped by the browse grid control I was using – it seemed to indicate that I was on a record when in reality it wasn’t. Another case of model does not match the implementation.

New on the blogroll… davetron

I finally got someone to send me/link to The Chronicles of Davetron, where I discovered that he qualified for the Winter Olympics in the skeleton. Let me tell you that since I’ve know Dave he’s always been a fanatic for the sports, and to find this out I am just as proud as punch. While we partied he trained, and now he gets to represent the country at the Olympics – it just brings a tear to my bitter eyes.

The winnah and champeen of the world

The godchild was in a table quiz tonight and he won! we were all surprised. while we were going home he asked a question about the internet – basically claiming that the internet was invented in 1990. I had to correct him, of course that it was the world wide web. Then I decided to explain the 7 layer OSI model to him. I think he regretted having made the slight factual error at the beginning. In the end, I explained to him that the web operated as a level 7 protocol; or in the parlance of Arthur C. Clarke; is indistinguishable from magic. It would have driven him to sleep if it wasn’t for the vast amount of soda he had consumed.

the don’t bloody patronize me button

this site is not designed for minors. With that in mind we have created this really crappy test for you. If you can input a date of birth that means you are over a certain age then we will permit you entrance to our web site, otherwise please leave.
Problem number 1, anyone over the age of 18 (or, shock horror for drinks sites 21) gets sick of these things coming up so often. I mean come on people, just a button saying ‘i agree, I’m over the required age’ is a much better mechanism, because invariably the implementors of the web site in question have used some gorram flash animation that doesn’t take key input, and can’t deal with nerds typing dates.
The only time I got a kick out of something that insisted I was over a certain age asked me questions that were unlikely to be known by an under 18. The game was Leisure Suit Larry and it had a good collection of questions. I’m not certain, but I think they were age related, so if you claimed you were of a certain age then a different set of questions were sourced. you had to get three questions correct, and could fail two, after which it kicked you out.