2

I want to get some unique machine information using a firefox add-on.

With this code I can get the name:

var dns = Cu.components.classes["@mozilla.org/network/dns-service;1"]
                    .getService(Cu.components.interfaces.nsIDNSService);
var myName = dns.myHostName;

Now I need NIC information (Like mac address, adapter name). I trying to use getAdaptersInfo function, but this will work only for Windows, and I need some solution cross platform.

Anyone has an idea?

This is my code for getAdaptersInfo:

function getMacAddress(){

    const MAX_ADAPTER_NAME_LENGTH = 256;
    const MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
    const ERROR_BUFFER_OVERFLOW = 111;
    const NO_ERROR = 0;

    var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
        {'String': ctypes.char}
        ]);


    var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
    IP_ADDR_STRING.define([
        {'Next': IP_ADDR_STRING.ptr},
        {'IpAddress': IP_ADDRESS_STRING},
        {'IpMask': IP_ADDRESS_STRING},
        {'Context': ctypes.long}
        ]);


    var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');

    const DWORD = ctypes.uint32_t;

    IP_ADAPTER_INFO.define([
        {'Next': IP_ADAPTER_INFO.ptr},
        {'ComboIndex': DWORD},
        {'AdapterName': ctypes.char},
        {'Description': ctypes.char},
        {'AddressLength': ctypes.int32_t},
        {'Address': ctypes.uint8_t.array(10).ptr},
        {'Index': DWORD},
        {'Type': ctypes.uintptr_t},
        {'DhcpEnabled': ctypes.uintptr_t},
        {'CurrentIpAddress': IP_ADDR_STRING.ptr},
        {'IpAddressList': IP_ADDR_STRING},
        {'GatewayList' : IP_ADDR_STRING},
        {'DhcpServer': IP_ADDR_STRING},
        {'HaveWins': ctypes.int32_t},
        {'PrimaryWinsServer': IP_ADDR_STRING},
        {'SecondaryWinsServer':IP_ADDR_STRING},
        {'LeaseObtained': ctypes.uintptr_t},
        {'LeaseExpires': ctypes.uintptr_t}
        ]);

    const nomes = [ctypes.libraryName('IPHLPAPI')];
    const lib = loadLibrary(nomes);

    try{
        if(!lib)
            return null

        console.log("Biblioteca aberta!");

        /*DWORD GetAdaptersInfo(
          _Out_    PIP_ADAPTER_INFO pAdapterInfo,
          _Inout_  PULONG pOutBufLen
        );*/
        var getAdaptersInfo = lib.declare(
            "GetAdaptersInfo", 
            ctypes.default_abi,
            DWORD,
            IP_ADAPTER_INFO.ptr,
            ctypes.long.ptr);


        let buf = (IP_ADAPTER_INFO)();
        let pbuf = buf.address();

        let ret = ctypes.long(2000);
        let pret = ret.address();

        let sts = getAdaptersInfo(pbuf,pret);

        if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
            buf = null;
            //agora mando novamente usando o que a lib me retornou.
            sts = getAdaptersInfo(pbuf,pret);
        }

        if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
            throw Error("Erro buscando configuracoes do adaptador.");
        }

    }catch(ex){
        console.log("Erro na biblioteca", ex, ex.message);
    }finally{
        lib.close();
    }

}

But firefox crash when I run cfx run.

Noitidart
  • 35,443
  • 37
  • 154
  • 323
Raphael
  • 83
  • 6
  • Will loook into when i get a chance, very busy with one of my own projecs rights now. Check out this topic though: http://stackoverflow.com/questions/28223087/how-can-i-allow-firefox-or-chrome-to-read-a-pcs-hostname-or-other-assignable – Noitidart Mar 27 '15 at 18:17
  • Thank you. The solution on this topic is very cool but I need some information more exclusive, like mac address. – Raphael Mar 27 '15 at 19:33
  • I will try different things too, like generate an unique id and save somewhere (maybe simple storage) – Raphael Mar 27 '15 at 19:40

2 Answers2

2

Ignore this solution it is very wrong - see my 2nd solution its a work in progress right now

Your code works, just had to access the .contents of pbuf, copy paste the code below to scratchpad and set environment to browser and hit run. See here on how to enable browser environment from scratchpad: Youtube :: How to Enable Scratchpad Environment - Browser

Cu.import('resource://gre/modules/ctypes.jsm');
function getMacAddress(){

    const MAX_ADAPTER_NAME_LENGTH = 256;
    const MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
    const ERROR_BUFFER_OVERFLOW = 111;
    const NO_ERROR = 0;
    const MAX_ADAPTER_ADDRESS_LENGTH = 8;

    var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
        {'String': ctypes.char.array(4 * 4)}
        ]);


    const DWORD = ctypes.uint32_t;

    var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
    IP_ADDR_STRING.define([
        {'Next': IP_ADDR_STRING.ptr},
        {'IpAddress': IP_ADDRESS_STRING},
        {'IpMask': IP_ADDRESS_STRING},
        {'Context': DWORD}
    ]);
    var PIP_ADDR_STRING = IP_ADDR_STRING.ptr;
    var time_t = ctypes.long; // based on this github search https://github.com/search?utf8=%E2%9C%93&q=time_t+ctypes&type=Code&ref=searchresults AND based on this answer here: http://stackoverflow.com/a/471287/1828637

    var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');

    IP_ADAPTER_INFO.define([ // have to use .define because one of the fields "Next" is a ptr to itself
        {'Next': IP_ADAPTER_INFO.ptr},
        {'ComboIndex': DWORD},
        {'AdapterName': ctypes.char.array(MAX_ADAPTER_NAME_LENGTH + 4)},
        {'Description': ctypes.char.array(MAX_ADAPTER_DESCRIPTION_LENGTH + 4)},
        {'AddressLength': ctypes.unsigned_int},
        {'Address': ctypes.unsigned_char.array(MAX_ADAPTER_ADDRESS_LENGTH)}, // BYTE is ctypes.unsigned_char
        {'Index': DWORD},
        {'Type': ctypes.unsigned_int},
        {'DhcpEnabled': ctypes.unsigned_int},
        {'CurrentIpAddress': PIP_ADDR_STRING},
        {'IpAddressList': IP_ADDR_STRING},
        {'GatewayList' : IP_ADDR_STRING},
        {'DhcpServer': IP_ADDR_STRING},
        {'HaveWins': ctypes.bool},
        {'PrimaryWinsServer': IP_ADDR_STRING},
        {'SecondaryWinsServer':IP_ADDR_STRING},
        {'LeaseObtained': time_t},
        {'LeaseExpires': time_t}
        ])

    const lib = ctypes.open(ctypes.libraryName('IPHLPAPI'));

    try{
        if(!lib)
            return null

        console.log("Biblioteca aberta!");

        /*DWORD GetAdaptersInfo(
          _Out_    PIP_ADAPTER_INFO pAdapterInfo,
          _Inout_  PULONG pOutBufLen
        );*/
        var getAdaptersInfo = lib.declare(
            "GetAdaptersInfo", 
            ctypes.default_abi,
            DWORD,
            IP_ADAPTER_INFO.ptr,
            ctypes.long.ptr);


        let buf = (IP_ADAPTER_INFO)();
        let pbuf = buf.address();

        let ret = ctypes.long(2000);
        let pret = ret.address();

        let sts = getAdaptersInfo(pbuf,pret);

        if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
            buf = null;
            //agora mando novamente usando o que a lib me retornou.
            sts = getAdaptersInfo(pbuf,pret);
        } else {
            console.log('got it', pbuf.contents.toString());
        }

        if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
            throw Error("Erro buscando configuracoes do adaptador.");
        }

    }catch(ex){
        console.log("Erro na biblioteca", ex, ex.message);
    }finally{
        lib.close();
    }

}

getMacAddress();

Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • Hi, Thank you! Do you tested wich OS? Using Windows 8 firefox crash when I run this code. Do you know why? – Raphael Mar 28 '15 at 14:29
  • I used Windows 8.1. I'll test onWin7 and WinXP and report back, did you copy paste exactly what I put here? Oh whoops it crashed on Win81 for me too let me revise the code. – Noitidart Mar 28 '15 at 19:49
  • Ok at @Sabbathman copy paste now it will work. Before I didn't review the WinAPI stuff and a bunch of your types were wrong. Tested on Win81 and WinXP. My Win7 machine was having network problems so this code kept trying to access some information which isn't available so it would crash but that's expected. So if there are network problems it crashes if you run this, so you have to figure out what thos network problems are and detect them before running this code. When you find that out please do share. – Noitidart Mar 28 '15 at 20:22
  • Actually i dont know why it was crashing on my Win7 there are some comments here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365917%28v=vs.85%29.aspx please share when you figure that out. The code should be good though. It works in XP and 8.1 – Noitidart Mar 28 '15 at 20:33
  • Thank you @Noitidart. On my windows 8 it is crashing yet, I will try to figure this out. – Raphael Mar 30 '15 at 11:10
  • Sorry, it was crashing only in scratchpad. Using `cfx run` it works! – Raphael Mar 30 '15 at 11:17
  • @Sabbathman that's weird, do you have a win7 machine to test on, this shouldn't crash from scratchpad. – Noitidart Mar 30 '15 at 15:19
  • 1
    Yes, so weird... I have, I'll test soon and report here. – Raphael Mar 30 '15 at 16:01
  • Thanks keep me posted please I'm hoping to resolve all crash issues with this. :) – Noitidart Mar 30 '15 at 16:09
1

Ok now THIS works :) The issue was I was telling the function to accept list of structures by defining it as this IP_ADAPTER_INFO.ptr.array() then I was creating an array of structures like this let pbuf = IP_ADAPTER_INFO.ptr.array(1)() however this would crash, and when we increased to sizes of 2 or more it crashed faster. So I changed up to declare it like this in the function IP_ADAPTER_INFO.ptr and then I create an array of structs like this let pbuv = IP_ADAPTER_INFO.array(?) where ? can be any number and it works fine :)

Cu.import('resource://gre/modules/ctypes.jsm');
function getMacAddress(){

    var MAX_ADAPTER_NAME_LENGTH = 256;
    var MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
    var ERROR_BUFFER_OVERFLOW = 111;
    var NO_ERROR = 0;
    var MAX_ADAPTER_ADDRESS_LENGTH = 8;

    var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
        {'String': ctypes.char.array(4 * 4)}
    ]);

    var IP_MASK_STRING = ctypes.StructType('IP_MASK_STRING',[
        {'String': ctypes.char.array(4 * 4)}
    ]);


    var DWORD = ctypes.unsigned_long;

    var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
    IP_ADDR_STRING.define([
        {'Next': IP_ADDR_STRING.ptr},
        {'IpAddress': IP_ADDRESS_STRING},
        {'IpMask': IP_MASK_STRING},
        {'Context': DWORD}
    ]);
    var PIP_ADDR_STRING = IP_ADDR_STRING.ptr;

    var time_t = ctypes.long; // based on this github search https://github.com/search?utf8=%E2%9C%93&q=time_t+ctypes&type=Code&ref=searchresults AND based on this answer here: http://stackoverflow.com/a/471287/1828637

    var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');

    IP_ADAPTER_INFO.define([ // have to use .define because one of the fields "Next" is a ptr to itself
        {'Next': IP_ADAPTER_INFO.ptr},
        {'ComboIndex': DWORD},
        {'AdapterName': ctypes.char.array(MAX_ADAPTER_NAME_LENGTH + 4)},
        {'Description': ctypes.char.array(MAX_ADAPTER_DESCRIPTION_LENGTH + 4)},
        {'AddressLength': ctypes.unsigned_int},
        {'Address': ctypes.unsigned_char.array(MAX_ADAPTER_ADDRESS_LENGTH)}, // BYTE is ctypes.unsigned_char
        {'Index': DWORD},
        {'Type': ctypes.unsigned_int},
        {'DhcpEnabled': ctypes.unsigned_int},
        {'CurrentIpAddress': PIP_ADDR_STRING},
        {'IpAddressList': IP_ADDR_STRING},
        {'GatewayList' : IP_ADDR_STRING},
        {'DhcpServer': IP_ADDR_STRING},
        {'HaveWins': ctypes.bool},
        {'PrimaryWinsServer': IP_ADDR_STRING},
        {'SecondaryWinsServer':IP_ADDR_STRING},
        {'LeaseObtained': time_t},
        {'LeaseExpires': time_t}
    ]);

    var lib = ctypes.open(ctypes.libraryName('IPHLPAPI'));

    try{
        if(!lib)
            return null

        console.log("Biblioteca aberta!");

        /*DWORD GetAdaptersInfo(
          _Out_    PIP_ADAPTER_INFO pAdapterInfo,
          _Inout_  PULONG pOutBufLen
        );*/
        var getAdaptersInfo = lib.declare("GetAdaptersInfo", ctypes.winapi_abi,
            DWORD,
            IP_ADAPTER_INFO.array(),
            ctypes.unsigned_long.ptr
        );


        let pbuf = IP_ADAPTER_INFO.array(0)();
        console.info('pbuf.length:', pbuf, pbuf.length, 'IP_ADAPTER_INFO.size:', IP_ADAPTER_INFO.size, 'pbuf size:', pbuf.length * IP_ADAPTER_INFO.size);
        let ret = ctypes.unsigned_long(pbuf.length * IP_ADAPTER_INFO.size);

        let sts = getAdaptersInfo(pbuf, ret.address()); // initial fetch to get size needed
        console.info('sts:', ctypes.UInt64.lo(sts));
        console.info('sts:', sts, sts.toString(), uneval(sts));
        console.info('ret:', ret, ret.toString(), uneval(ret));

        if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
            // ret is defined as unsigned_long which is always a UInt64 in jsctypes `CData { value: UInt64 } `
            var ret_jsInt = parseInt(ret.value.toString());
            console.info('ret_jsInt:', ret_jsInt);
            var neededLength = Math.round(ret_jsInt / IP_ADAPTER_INFO.size);
            pbuf = IP_ADAPTER_INFO.array(neededLength)();
            console.info('pbuf RE-size:', pbuf.length * IP_ADAPTER_INFO.size);

            if (pbuf.length * IP_ADAPTER_INFO.size != ret_jsInt) {
                throw new Error('winapi says the size needed is ' + ret_jsInt + ' and i calculated the length by dividing the ID_ADAPTER_INFO.size which is ' + ID_ADAPTER_INFO.size + ' so the needed length was  ' + neededLength + ' but the size of this list of neededLength DOES NOT match what winapi says it needs, the size of the neededLength resized list is ' + (pbuf.length * IP_ADAPTER_INFO.size));
            }

            //agora mando novamente usando o que a lib me retornou.
            console.error('going for 2nd time');

            sts = getAdaptersInfo(pbuf, ret.address()); // we just pass same ret, as it was updated to the right size // crashing here!!!
            if (sts != NO_ERROR) {
                throw new Error('after 2nd fetch it still failed, now i need to add more error handling here, error was: ' + sts.toString());
            } else {
                console.info('succesfully obtained after 2nd time:', pbuf.toString());
                for (var i=0; i<pbuf.length; i++) {
                    console.log(i, pbuf[i].addressOfField('AdapterName').contents.readString(), pbuf[i].addressOfField('IpAddressList').contents.IpAddress.String.readString(), pbuf[i].addressOfField('Description').contents.readString());
                }
            }
        } else {
            console.error('this should never happen! i passed 0 size into it it should always overflow!! unless there is no adapater info but there has to be!!');
        }
        /*
        if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
            throw Error("Erro buscando configuracoes do adaptador.");
        }
        */

    }catch(ex){
        console.log("Erro na biblioteca", ex, ex.message);
    }finally{
        lib.close();
    }

}

getMacAddress();

OLD STUFF below - leaving here so i can learn from this as i first attempted to tell function to accept array by defning it as IP_ADAPTER_LIST.ptr.array() but i had to change that to IP_ADAPTER_LIST.ptr as as seen above


Whoa dude I'm looking at this more and it looks like it takes an array of IP_ADAPTER_INFOs doing this makes it not crash on Win7

I have an issue though, as ret comes back as saying the needed size is 2560. But the size of our IP_ADAPTER_INFO struct is 132. So 2560/132 = 19.333 so something is wrong with our structure we have to figure that out. never mind this i fixed the issue i had tetsed doing ctypes.char.array(4*4).ptr instead of just ctypes.char.array(4*4)

So this is where I figured out we need to pass an array of IP_ADAPTER_INFO: https://github.com/manimaul/Matrix-Mariner-GPS/blob/8989621dfda0e291820a37096d582cc1f355e346/src/getIPwin.py#L45

This is my work, so the issue right now is its crashing after 2nd fetch. we need to fix that.

edit: Ok dude this is definitely on the right track, its now crashing on the 2nd fetch on all systems, win7 and win81 (i didnt try xp but im sure it will), we have to figure out why on earth its crashing. if you comment out the second sts = getAdapters... it will not crash, we have to figure this out its bothering me haha

Cu.import('resource://gre/modules/ctypes.jsm');
function getMacAddress(){

    const MAX_ADAPTER_NAME_LENGTH = 256;
    const MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
    const ERROR_BUFFER_OVERFLOW = 111;
    const NO_ERROR = 0;
    const MAX_ADAPTER_ADDRESS_LENGTH = 8;

    var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
        {'String': ctypes.char.array(4 * 4)}
    ]);


    const DWORD = ctypes.uint32_t;

    var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
    IP_ADDR_STRING.define([
        {'Next': IP_ADDR_STRING.ptr},
        {'IpAddress': IP_ADDRESS_STRING},
        {'IpMask': IP_ADDRESS_STRING},
        {'Context': DWORD}
    ]);
    var PIP_ADDR_STRING = IP_ADDR_STRING.ptr;
    var time_t = ctypes.long; // based on this github search https://github.com/search?utf8=%E2%9C%93&q=time_t+ctypes&type=Code&ref=searchresults AND based on this answer here: http://stackoverflow.com/a/471287/1828637

    var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');

    IP_ADAPTER_INFO.define([ // have to use .define because one of the fields "Next" is a ptr to itself
        {'Next': IP_ADAPTER_INFO.ptr},
        {'ComboIndex': DWORD},
        {'AdapterName': ctypes.char.array(MAX_ADAPTER_NAME_LENGTH + 4)},
        {'Description': ctypes.char.array(MAX_ADAPTER_DESCRIPTION_LENGTH + 4)},
        {'AddressLength': ctypes.unsigned_int},
        {'Address': ctypes.unsigned_char.array(MAX_ADAPTER_ADDRESS_LENGTH)}, // BYTE is ctypes.unsigned_char
        {'Index': DWORD},
        {'Type': ctypes.unsigned_int},
        {'DhcpEnabled': ctypes.unsigned_int},
        {'CurrentIpAddress': PIP_ADDR_STRING},
        {'IpAddressList': IP_ADDR_STRING},
        {'GatewayList' : IP_ADDR_STRING},
        {'DhcpServer': IP_ADDR_STRING},
        {'HaveWins': ctypes.bool},
        {'PrimaryWinsServer': IP_ADDR_STRING},
        {'SecondaryWinsServer':IP_ADDR_STRING},
        {'LeaseObtained': time_t},
        {'LeaseExpires': time_t}
        ])

    const lib = ctypes.open(ctypes.libraryName('IPHLPAPI'));

    try{
        if(!lib)
            return null

        console.log("Biblioteca aberta!");

        /*DWORD GetAdaptersInfo(
          _Out_    PIP_ADAPTER_INFO pAdapterInfo,
          _Inout_  PULONG pOutBufLen
        );*/
        var getAdaptersInfo = lib.declare(
            "GetAdaptersInfo", 
            ctypes.default_abi,
            DWORD,
            IP_ADAPTER_INFO.ptr.array(),
            ctypes.unsigned_long.ptr);


        let pbuf = IP_ADAPTER_INFO.ptr.array(1)();
        console.info('pbuf.length:', pbuf.length, 'IP_ADAPTER_INFO.size:', IP_ADAPTER_INFO.size, 'pbuf size:', pbuf.length * IP_ADAPTER_INFO.size);
        let ret = ctypes.unsigned_long(pbuf.length * IP_ADAPTER_INFO.size);

        let sts = getAdaptersInfo(pbuf, ret.address()); // initial fetch to get size needed
        console.info('sts:', sts.toString(), 'ret:', ret.toString());

        if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
            // ret is defined as unsigned_long which is always a UInt64 in jsctypes `CData { value: UInt64 } `
            var ret_jsInt = parseInt(ret.value.toString());
            console.info('ret_jsInt:', ret_jsInt);
            var neededLength = ret_jsInt / IP_ADAPTER_INFO.size;
            pbuf = IP_ADAPTER_INFO.ptr.array(neededLength)();
            console.info('pbuf RE-size:', pbuf.length * IP_ADAPTER_INFO.size);
            if (pbuf.length * IP_ADAPTER_INFO.size != ret_jsInt) {
                throw new Error('winapi says the size needed is ' + ret_jsInt + ' and i calculated the length by dividing the ID_ADAPTER_INFO.size which is ' + ID_ADAPTER_INFO.size + ' so the needed length was  ' + neededLength + ' but the size of this list of neededLength DOES NOT match what winapi says it needs, the size of the neededLength resized list is ' + (pbuf.length * IP_ADAPTER_INFO.size));
            }
            //agora mando novamente usando o que a lib me retornou.
            console.error('going for 2nd time');

            //sts = getAdaptersInfo(pbuf, ret.address()); // we just pass same ret, as it was updated to the right size // crashing here!!!
            if (sts != NO_ERROR) {
                throw new Error('after 2nd fetch it still failed, now i need to add more error handling here, error was: ' + sts.toString());
            } else {
                console.info('succesfully obtained after 2nd time:');
            }
        } else {
            console.error('this should never happen! i passed 0 size into it it should always overflow!! unless there is no adapater info but there has to be!!');
        }
        /*
        if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
            throw Error("Erro buscando configuracoes do adaptador.");
        }
        */

    }catch(ex){
        console.log("Erro na biblioteca", ex, ex.message);
    }finally{
        lib.close();
    }

}

getMacAddress();
Noitidart
  • 35,443
  • 37
  • 154
  • 323
  • 1
    see the line thats commented out `// crashing here` i need help on getting that line to not crash. dont use the code above, use this code, its the right way to do it even though its crashing right now. – Noitidart Mar 31 '15 at 09:55
  • It is crashing only when I run second time. I think we need to clear something in the DLL. I will try to figure this out. Can we specify primary MAC Address? – Raphael Mar 31 '15 at 10:45
  • ok @Sabbathman solution found and posted, i left the old stuff, so we can see the differences and learn from it :) – Noitidart Mar 31 '15 at 16:50
  • Thank you @Noitidart, I certainly learned a lot with this issues. – Raphael Mar 31 '15 at 17:47
  • Cool @Sabbathman check out the edit, i just added more to the console.log of the results as it iterates through, so you know how to readString on the ip address contained within the IP_ADDR struct – Noitidart Mar 31 '15 at 17:57
  • 1
    Also for the abi i used ctypes.winapi_abi as my ff is 32bit, but for 64bit you have to use ctypes.default_abi as per: https://github.com/Noitidart/Profilist/blob/%2321/modules/ostypes_win.jsm#L19 – Noitidart Mar 31 '15 at 17:59