General => The Campus => Topic started by: colinr on November 05, 2019, 10:27:21 AM

I'm trying to figure out how to conduct comparison of 128-bit unsigned integers, I've been trying this for months without getting anywhere.

Essentially, I have a data set of IPv6 addresses, which comprises of a start address, end address and the two digit ISO country code to which this block of v6 addresses is assigned to. These are stored as 128-bit little endian integers, and I would like to iterate through this data set to establish which block a particular IP address sits.

So, I'm not testing for equality, but rather if the IP address that I'm looking for is greater or less than each of these blocks.

This is a sample that is suitable when all ranges are contiguous (i.e no empty IPs zones between ranges). So, here you don't need to know about the End IP. Were the ranges not contiguous you might have multiple Start IPs above your test IP, so you would need to check the End IP to decide what is the country.

Here, this is done with vector instructions SSE 4.1. Everybody has that (except here, some people don't).

You don't need to change anything. Paste exactly what is above in Notepad and save as test.asm. Use a recent version of MASM (they come free with Visual Studio community edition). The MASM that comes with MASM32 predates SSE.

It's probably the jump condition that I'm getting wrong, but in the sample posted below, I kind of thought that the first instance of the test should fail and and jump back into the loop as the sample IP address should fit within the second block (GB).

The code at the beginning is simply to swap the Endianness to allow the IP addresses to be viewed easier.

I replaced jnz with jb and it appeared to work, but will need to do further testing to make sure, I think it would also be prudent to test against the end address too.

If you begin at the starting offset plus the offset for the member you are after, then you just ADD that data length to get the next member offset in the following data set. If I was working on a data set of this type, I would construct an array of pointers to the start of each data set then just reference the data set plus offset You will find techniques of this type reasonably fast.

Well, my example is broken :sad:What happens is that PCMPGTQ makes a signed compare. So my example worked but you choose an IP where this qword 0ac528803h0001b9000h is negative. I am not seeing another easy SSE solution at the moment because there is no equivalent packed unsigned compare. Probably you should try to do it using General Purpose Registers as suggested here http://masm32.com/board/index.php?topic=8148.msg89445#msg89445.

I'll have to throw that one into OllyDbg as I tend not to use the if statement to figure out what's going on.

Like I said earlier, your previous example, by using jb instead of jnz appears to work just fine.

The data set has now been converted to little endian so I can get rid of all that horrible byte order swapping nonsense.

Slightly off topic, but as I've previously said, I've been using WinAsm Studio and a legacy version of MASM32 (now updated), what would your recommendations be for an IDE to replace WinAsm Studio (ideally one that will support x86 and x64 using MASM32 and MASM64) and a debugger that will support x86/x64 to replace OllyDbg.

Slightly off topic, but as I've previously said, I've been using WinAsm Studio and a legacy version of MASM32 (now updated), what would your recommendations be for an IDE to replace WinAsm Studio (ideally one that will support x86 and x64 using MASM32 and MASM64) and a debugger that will support x86/x64 to replace OllyDbg.

This is a matter of personal preferences. I use Notepad++ as an editor for masm and an editor for many other things, so it is always open. Sometimes I use Visual Studio as well for masm when I am doing a masm module for HLL. This is very handy because it builds everything at the same time and the VS debugger is top notch.

I've implemented the new code that you wrote into my project (after reversing it), and initial testing (with 1 IP) indicates that it may be working, however, there were a couple of bugs.

I you take a look at labels L0085100F and L00851050, they were originally on the next instruction down (CMP), I found that EAX was being trashed by the value written to EAX from EDI+8, thus causing the lookup to fail. I suppose I could optomise this by using EBX instead of EAX, and save some cycles instead of reading EDI+12 on each iteration that it returns here.

Other than that, thank's very much for helping me out with this, what in theory is easy to achieve proved extremely difficult.

I also don't understand what condition would cause L008510A2 to be reached.

Before I look at the code, make sure you are using the latest releases either of VS 2017 or 2019 because there was a "while" bug only recently fixed.Either way, what I made was just a sketch. I can't spend much more time with that. It is a good exercise for you.