Movies TV Comics. Star Wars Marvel. Filed under: News PC Windows. By Owen S. Good Jun 20, , pm EDT. Reddit Pocket Flipboard Email. Well, it appears it array is returned from EnumerateProcessNames , much like Bob's address is returned in Paul's answer to Alice.
So who is our Alice, and why is she asking? We could keep moving up frame-by-frame, but let's first demystify the call stack a bit. We can do this by looking at multiple call stacks from multiple events at very different points in the event trace.
The only thing these events must have in common in their thread id. A thread is an execution context, a universe in which a piece of code executes. Any code executing in the same thread will have a common origin, each event just being part of a large cascade of function calls all acting as a single unit. Thus, by comparing multiple call stacks on the same thread, we can identify common code as well as points of divergence. If we go back to our previous thought experiment, we can generalize this.
Let's say Alice does a lot of other things throughout her day, and that she does one at a time. Restating: she starts one task, waits for it to finish, and then starts another. If we made call stacks for all of her tasks, each one would have her at the bottom.
As tasks break into sub-tasks, many call stacks would share more and more bottom-most frames in common. Taking our previous example, let's say Alice also asks Paul for Jim's address. Paul doesn't know, so he asks Tom. Let's put these call stacks side-by-side, aligning them at the bottom:. Even though the call stacks differ in depth, we can clearly see a common point of origin.
Beyond the common origin is the point of divergence. So, let's take four very different events and compare their call stacks; the event we've been looking at is second from left:. In green, we can see a common origin. This is likely a result of setting up the program and preparing to execute.
In blue, we see the first divergence point. The left pair shares offset 0xae1 and the right shares 0xb Notice that both start with 0x , differing only in the three final digits. If we go to either of these offsets in Binary Ninja, we see they are actually a part of the same function. Poking around this function, we see strings referencing WindowsPortalMain.
Moreover, it tells us that the code in this thread is likely all related in some way to the user interface, and the divergence we see might relate to different UI elements. In red, we see another common branch, with the divergence point in pink. The offsets at divergence are wildly different this time around. We would expect to diverge in similar code, as we saw before, so this is interesting. If we look at the code, we can see why:. Normally, functions are called directly.
Tracing backwards, we can see more code related to arrays. We can also see that this all happens in a fat loop. Or: this part of the program is responsible for executing various different tasks; the task we're trying to unravel is one of them. For simplicity, let's call this frame Dispatcher. Okay, so we're missing part of the big picture in frame It may seem counterintuitive to dissect it, since we know it's not specific to the process-related code, but let's do it anyways.
If we jump to it in Binary Ninja and look around, we'll find code referencing this string:. At this point, we know what most of the 28 frames are doing. It's frames that are still a mystery. To dig deeper, we need to start dynamic analysis , which we'll do with x64dbg. Like Binary Ninja, this will give us access to the program's assembly code. In addition, however, it allows us to debug the process. This means we can breakpoint function calls, look at memory, and more.
Imagine a debugger as a third-party, let's call him Nick. At any point, Nick can interrupt Alice, Paul, or Jim to ask what they're doing, what they're thinking about, what they're going to do next, and so on. Interrupting someone is called a breakpoint , we say it is hit when the interruption happens. By inspecting memory , registers , and assembly code while a breakpoint is hit, we can figure out what the code is thinking and what it'll do next.
We still have some frames to demystify. Let's set breakpoints on each of them, restart the program fresh, and let it execute until the topmost frame has been hit. What we see is very telling:. The first obvious thing is that frames 18 and 19 aren't related to process enumeration. They are very busy doing a lot of things, meanwhile process enumeration has only happened once. The second is that frame 20 must have a ton of responsibilities, as it has waited for dozens of calls without having anything returned implying there's a lot of stuff that has to finish before it is done working.
The final takeaway is that frames 15, 16, and 17 are likely closely related, as they are executing in lockstep. This is where we should try to find the actual behavior.
Note: you might wonder why we didn't do this before, why we would have bothered comparing call stacks manually. The answer is simple: it's likely that there would be thousands or tens of thousands of hits if we dropped breakpoints on every frame.
The stack comparisons let us narrow down the scope by a lot so that this method would be more manageable. Now, let's drop a breakpoint on frame This will be hit right when EnumerateProcessNames is complete. If we inspect the memory, we can confirm that it does indeed return an array of process names:.
That shows the first 4 entries. One peculiar thing is that the path is always of the EGS folder, not of the process in question. It's repeated over and over, full copies of this string. I spent a lot of time trying to get the next loop to do something. The first time this all happens, it gets bypassed completely. In subsequent executions, it seems to be comparing the new process list to the previous one; some sort of merge or dedupe. There are many statements which follow the loop that won't execute, even when patching values in.
If I'm being honest, I think it might have something to do with that potential bug; this code might actually not be working properly because of it. You may have noticed that I said subsequent lists are compared to their predecessors, and that may make you think "oh, so they're storing it! While they are, it doesn't seem to be consequential. I tried a lot of memory debugging techniques to see what other code could be touching the values and I came up completely dry.
I've kinda broken stride at this point because I hit the part of reversing where I had to follow a lot of rabbit holes, most of which didn't pan out. I did eventually try setting a memory breakpoint on the path, rather than the process name, and that actually got me somewhere. Back to our running thought experiment, a memory breakpoint is if Nick could say "let me know when you think about X" and anybody in the universe would tell him and allow him to interact with them before continuing.
Look, computers are weird. Not all of the analogies can make sense. This is calling a function which does case-insensitive string comparison. That is to say: it compares two pieces of text, ignoring case. The strings to check are passed along in two registers, and we can see them clearly:.
If we drop a breakpoint on this call and watch what comes through, we will see that the strings are always the same. Well, not actually.
The first string is always a different copy of the same string, and we can see that because the number beside RCX changes while the text remains the same.
Why is it a copy? Except they will never be, because they are always the same wrong path. I told you it's a bug.
It also appears that this is invoked via a chain of calls originating from frame 17, confirming that it's happening soon after the enumeration. That seems pretty innocuous. If we forget about the fact that the code doesn't seem to be working properly, we can come up with all sorts of reasonable explanations for why Epic might want to know if Fortnite is running. Possibly to display something in their community portal user interface? Now doesn't that just sound like almost any game store you've seen?
Sweeney does seem open to legitimate complaints about the platform too, stating that the lacking store features and exclusive games are a "fine target for ire". While Sweeney's comments likely won't stop online masses from attacking him or Epic, it may at least assuage the fears of some that don't want their personal information touched.
Regardless, Epic has a long way to go before they win over their naysayers, and it seems unlikely that the company will ever be able to completely do so. However, Epic is a major company with deep pockets and a sizeable war chest, with Epic being worth 8 billion dollars , and it seems like they're prepared to wage a war of attrition with Steam if need be. The Epic Games Store gives away a new free game while confirming the free game that's coming next week on Thursday, January
0コメント