Reading real Value from Structure Object

292 views
Skip to first unread message

opa114

unread,
Dec 24, 2014, 8:44:04 AM12/24/14
to jna-...@googlegroups.com
How can iread the real value from a Structure Object.

I have ported a C++ Structure to JNA Java like this:

    public class CRYPT_INTEGER_BLOB extends Structure {
       
public int cbData;
       
public Pointer pbData;
       
       
public CRYPT_INTEGER_BLOB() {
           
super();
       
}
       
protected List<? > getFieldOrder() {
           
return Arrays.asList("cbData", "pbData");
       
}
       
/** @param pbData C type : BYTE* */
       
public CRYPT_INTEGER_BLOB(int cbData, Pointer pbData) {
           
super();
           
this.cbData = cbData;
           
this.pbData = pbData;
       
}
       
public CRYPT_INTEGER_BLOB(Pointer peer) {
           
super(peer);
       
}
       
protected ByReference newByReference() { return new ByReference(); }
       
protected ByValue newByValue() { return new ByValue(); }
       
protected CRYPT_INTEGER_BLOB newInstance() { return new CRYPT_INTEGER_BLOB(); }
       
//public static CRYPT_INTEGER_BLOB[] newArray(int arrayLength) {
       
//    return Structure.newArray(CRYPT_INTEGER_BLOB.class, arrayLength);
       
//}
       
public static class ByReference extends CRYPT_INTEGER_BLOB implements Structure.ByReference {
           
       
};
       
public static class ByValue extends CRYPT_INTEGER_BLOB implements Structure.ByValue {
           
       
};
   
}

When i print out the cbData or pbData variable i get only the memory addresses:

  int cbData@0=b4b000
 
Pointer pbData@8=native@0x3f394bdc111f

And when i access the variable directly via the cbData or pbData vairable i get this value: 5263568 but expected output should be: ‎3d 36 b9 9b b5 f6 6e 33 e7 e3 14 d9 df dc 5e 7d 64 5c 3f 90 (which is the serial number of a certificate).

So how could i access the real data in my class above?

And why did newArray (see code above whitch is commented out) not exists in your JNA Structure class? it givesme the error that it does not exist? Sowhat is the up to date method?

Thanks and merry Christmas :)

opa114

unread,
Dec 29, 2014, 1:52:13 PM12/29/14
to jna-...@googlegroups.com
i solved it for the pointer values, but not for the int value. how can read teh real int value from int cbData?

Timothy Wall

unread,
Dec 29, 2014, 7:30:35 PM12/29/14
to jna-...@googlegroups.com
Edit your pointer-based constructor to look like this, so that it synchs from native memory on object creation:

public CRYPT_INTEGER_BLOB(Pointer peer) {
super(peer);
read();
}

If you want to create an array of struct based on a single address, use Structure.toArray(), not “newArray”.

> On Dec 29, 2014, at 1:52 PM, opa114 <opa...@gmail.com> wrote:
>
> i solved it for the pointer values, but not for the int value. how can read teh real int value from int cbData?
>
> --
> You received this message because you are subscribed to the Google Groups "Java Native Access" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

opa114

unread,
Dec 30, 2014, 9:25:11 AM12/30/14
to jna-...@googlegroups.com
i tried it bu no success.

Here are my Structure classes:

public class CERT_CONTEXT extends Structure {
   
   
public int dwCertEncodingType;
   
public Pointer pbCertEncoded;
   
public int cbCertEncoded;
   
public CERT_INFO pCertInfo;
   
public HANDLE hCertStore;
   
   
public CERT_CONTEXT() {

       
super();
   
}

   
protected List<? > getFieldOrder() {

       
return Arrays.asList("dwCertEncodingType", "pbCertEncoded", "cbCertEncoded", "pCertInfo", "hCertStore");
   
}
       
   
/**
         * @param pbCertEncoded C type : BYTE*<br>
         * @param pCertInfo C type : PCERT_INFO<br>
         * @param hCertStore C type : HCERTSTORE
         */

       
public CERT_CONTEXT(int dwCertEncodingType, Pointer pbCertEncoded, int cbCertEncoded, CERT_INFO pCertInfo, HANDLE hCertStore) {
           
super();
           
this.dwCertEncodingType = dwCertEncodingType;
           
this.pbCertEncoded = pbCertEncoded;
           
this.cbCertEncoded = cbCertEncoded;
           
this.pCertInfo = pCertInfo;
           
this.hCertStore = hCertStore;
       
}
       
public CERT_CONTEXT(Pointer peer) {
           
super(peer);
       
}
       
public static class ByReference extends CERT_CONTEXT implements Structure.ByReference {
           
       
};
       
public static class ByValue extends CERT_CONTEXT implements Structure.ByValue {
           
       
};
   
 
}

public class CERT_INFO extends Structure {
   
   
public int dwVersion;
   
public CRYPT_INTEGER_BLOB SerialNumber;
   
public CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
   
public CRYPT_INTEGER_BLOB Issuer;
   
public FILETIME NotBefore;
   
public FILETIME NotAfter;
   
public CRYPT_INTEGER_BLOB Subject;
   
public CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
   
public CRYPT_BIT_BLOB IssuerUniqueId;
   
public CRYPT_BIT_BLOB SubjectUniqueId;
   
public int cExtension;
   
public int rgExtension;
   
   
public CERT_INFO() {
       
super();
        read
();
   
}
   
   
protected List<? > getFieldOrder() {
       
return Arrays.asList("dwVersion", "SerialNumber", "SignatureAlgorithm", "Issuer", "NotBefore", "NotAfter", "Subject", "SubjectPublicKeyInfo", "IssuerUniqueId", "SubjectUniqueId", "cExtension", "rgExtension");
   
}
   
   
public CERT_INFO(Pointer peer) {
       
super(peer);
        read
();
   
}
           
   
public static class ByReference extends CERT_INFO implements Structure.ByReference {};
   
public static class ByValue extends CERT_INFO implements Structure.ByValue {};

 
}

public interface WindowsLibrary extends Crypt32 {
   
   
/** Opens a certificate store using a specified store provider type.
     * <pre>
     * HCERTSTORE WINAPI CertOpenStore(
     *     _In_ LPCSTR lpszStoreProvider
     *        _In_ DWORD dwMsgAndCertEncodingType:
     *     _In_ HCRYPTPROV hCryptProv
     *     _In_ DWORD dwFlags
     *     _In_ const void* pvPara
     * );
     * </pre>
     *
     * For more Details visit: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa376559%28v=vs.85%29.aspx">MSDN - CertOpenStore</a>
     */

   
public int CertOpenStore(
           
int lpszStoreProvider,
           
int dwMsgAndCertEncodingType,
            HANDLE hCryptProv
,
           
int dwFlags,
           
String pvPara
   
);
   
   
/** Retrieves the first or next certificate in a certificate store. Used in a loop, this function can retrieve in sequence all certificates in a certificate store.
     * <pre>
     * PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(
     *     _In_ HCERTSTORE hCertStore
     *     _In_ PCCERT_CONTEXT pPrevCertContext
     * );
     * </pre>
     *
     * For more Details visit: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa376050%28v=vs.85%29.aspx">MSDN - CertEnumCertificatesInStore</a>
     */

   
public CERT_CONTEXT CertEnumCertificatesInStore(
           
int certStore,
            CERT_CONTEXT certContext
   
);
   

           
   
WindowsLibrary INSTANCE = (WindowsLibrary) Native.loadLibrary("crypt32", WindowsLibrary.class);
}


Here i want to read the Value from dwVersion in CERT_INFO Class.

This is my main:


int lpszStoreProvider = 9;
int dwMsgAndCertEncodingType = 0;
HANDLE hCryptProv
= null;
int dwFlags = 65536|0x00004000;
String pvPara = "MY";
CERT_CONTEXT certContext
= null;

int store = WindowsLibrary.INSTANCE.CertOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
       
certContext
= WindowsLibrary.INSTANCE.CertEnumCertificatesInStore(store, certContext);

System.out.println(certContext.pCertInfo.dwVersion);

Here my output is a digital number like: 8577168. But the expected output should be 3 (because it is a Certificate with Version V3) Maybe a V2 Version, so Output should be 2. But i did not get this Output.




Timothy Wall

unread,
Dec 31, 2014, 9:38:48 AM12/31/14
to jna-...@googlegroups.com
Set the system property “jna.dump_memory=true” and call toString() on the Structure. That will show you the contents of native memory so you can see where things line up or not.

opa114

unread,
Jan 1, 2015, 2:06:37 PM1/1/15
to jna-...@googlegroups.com
CERT_INFO(native@0xf9a898) (200 bytes) {
 
int dwVersion@0=faef70
  CRYPT_INTEGER_BLOB
SerialNumber@8=CRYPT_INTEGER_BLOB(native@0xf9a8a0) (16 bytes) {
   
int cbData@0=f96350
   
Pointer pbData@8=null
 
}
  CRYPT_ALGORITHM_IDENTIFIER
SignatureAlgorithm@18=CRYPT_ALGORITHM_IDENTIFIER(native@0xf9a8b0) (24 bytes) {
   
WTypes$LPSTR pszObjId@0=null
    CRYPT_INTEGER_BLOB
Parameters@8=CRYPT_INTEGER_BLOB(native@0xf9a8b8) (16 bytes) {
     
int cbData@0=7c3016f4
     
Pointer pbData@8=native@0xf9a760
   
}
 
}
  CRYPT_INTEGER_BLOB
Issuer@30=CRYPT_INTEGER_BLOB(native@0xf9a8c8) (16 bytes) {
   
int cbData@0=ffffffff
   
Pointer pbData@8=native@0xffffffff
 
}
 
WinBase$FILETIME NotBefore@40=WinBase$FILETIME(native@0xf9a8d8) (8 bytes) {
   
int dwLowDateTime@0=0
   
int dwHighDateTime@4=0
 
}
 
WinBase$FILETIME NotAfter@48=WinBase$FILETIME(native@0xf9a8e0) (8 bytes) {
   
int dwLowDateTime@0=0
   
int dwHighDateTime@4=0
 
}
  CRYPT_INTEGER_BLOB
Subject@50=CRYPT_INTEGER_BLOB(native@0xf9a8e8) (16 bytes) {
   
int cbData@0=20007d0
   
Pointer pbData@8=null
 
}
  CERT_PUBLIC_KEY_INFO
SubjectPublicKeyInfo@60=CERT_PUBLIC_KEY_INFO(native@0xf9a8f8) (48 bytes) {
    CRYPT_ALGORITHM_IDENTIFIER
Algorithm@0=CRYPT_ALGORITHM_IDENTIFIER(native@0xf9a8f8) (24 bytes) {
     
WTypes$LPSTR pszObjId@0=null
      CRYPT_INTEGER_BLOB
Parameters@8=CRYPT_INTEGER_BLOB(native@0xf9a900) (16 bytes) {
       
int cbData@0=39c
       
Pointer pbData@8=native@0x44400
     
}
   
}
    CRYPT_BIT_BLOB
PublicKey@18=CRYPT_BIT_BLOB(native@0xf9a910) (24 bytes) {
     
int cbData@0=0
     
Pointer pbData@8=null
     
int cUnusedBits@10=f9a950
   
}
 
}
  CRYPT_BIT_BLOB
IssuerUniqueId@90=CRYPT_BIT_BLOB(native@0xf9a928) (24 bytes) {
   
int cbData@0=0
   
Pointer pbData@8=null
   
int cUnusedBits@10=0
 
}
  CRYPT_BIT_BLOB
SubjectUniqueId@a8=CRYPT_BIT_BLOB(native@0xf9a940) (24 bytes) {
   
int cbData@0=0
   
Pointer pbData@8=native@0xc00ba4a7c3016f4
   
int cUnusedBits@10=3a0043
 
}
 
int cExtension@c0=650073
 
int rgExtension@c4=730072
}
memory
dump
[70effa00]
[00000000]
[5063f900]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[f416307c]
[4aba0010]
[60a7f900]
[00000000]
[ffffffff]
[ffffffff]
[ffffffff]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[d0070002]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[9c030000]
[00000000]
[00440400]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[50a9f900]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[00000000]
[f416307c]
[4aba000c]
[43003a00]
[5c005500]
[73006500]
[72007300]

Thats my Output on first run. But i want the read the real Values not the Memory Addresses.

Timothy Wall

unread,
Jan 1, 2015, 7:51:44 PM1/1/15
to jna-...@googlegroups.com
Look at the memory dump and try to match up recognizable values with their corresponding fields. That may help you identify missing fields or places where extra structure padding is necessary in order to shift the values around.
Message has been deleted

opa114

unread,
Jan 2, 2015, 12:43:40 PM1/2/15
to jna-...@googlegroups.com
i've done it. but i want to read out the real value which is stored under the memory address. in my case i should gte the int value 2 or 3 by accessing the dwVersion. But i get the memory address. but how can i read the data which is stored under that address?

opa114

unread,
Jan 6, 2015, 12:03:46 PM1/6/15
to jna-...@googlegroups.com
no idea? :(

opa114

unread,
Jan 6, 2015, 12:39:52 PM1/6/15
to jna-...@googlegroups.com
when i convert the certificate to an X509 Certificate and print it out all the values are right. So the memory addresses from above are correct, but HOW can in read them directly from the given memory address?

Timothy Wall

unread,
Jan 6, 2015, 5:35:06 PM1/6/15
to jna-...@googlegroups.com
Your CERT_CONTEXT’s “pCertInfo" field needs to be of type Structure.ByReference. Using a vanilla CERT_INFO struct puts the structure inline into the enclosing structure (effectively “by value”).




> On Jan 2, 2015, at 12:43 PM, opa114 <opa...@gmail.com> wrote:
>
> i've done it. but i want to read out the real value which is stored under the memory address. in my case i should gte the int value 2 or 3 by accessing the dwVersion. But i get the memory address. but how can i read the data which is stored under that address?
>

opa114

unread,
Jan 7, 2015, 6:22:36 AM1/7/15
to jna-...@googlegroups.com
thank you very much. with Structure.ByRefernce it is working right now!

opa114

unread,
Jan 7, 2015, 7:07:14 AM1/7/15
to jna-...@googlegroups.com

Another small question. Hope you could help again:

When i read a ByteArray from a Pointer in my Structure and convert the byteArray to a String i get mysterious characters (see attachment)

This is the corresponding structure to it:

public class CRYPT_INTEGER_BLOB extends Structure {
   
   
public int cbData;

   
/** C type : BYTE* */
   
public Pointer pbData;
   
public CRYPT_INTEGER_BLOB() {

       
super();
        read
();
   
}
   
protected List<? > getFieldOrder() {

       
return Arrays.asList("cbData", "pbData");
   
}
   
/** @param pbData C type : BYTE* */
   
public CRYPT_INTEGER_BLOB(int cbData, Pointer pbData) {
       
super();
       
this.cbData = cbData;
       
this.pbData = pbData;
   
}

   
public CRYPT_INTEGER_BLOB(Pointer peer) {
       
super(peer);
        read
();
   
}
   
public static class ByReference extends CRYPT_INTEGER_BLOB implements Structure.ByReference {};
   
public static class ByValue extends CRYPT_INTEGER_BLOB implements Structure.ByValue {};
}

I think it is only a little problem, but i'm stuck on it.
Unbenannt.PNG

Kustaa Nyholm

unread,
Jan 7, 2015, 7:55:36 AM1/7/15
to jna-...@googlegroups.com
And how do you convert it to String?

new String(bytes) perhaps?

Did you read the javadoc:


At very least you should be using:


I get the feeling from your questions that your approach to your programming is somehow,
how would I say, "shallow"...''

br Kusti



--
You received this message because you are subscribed to the Google Groups "Java Native Access" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


This e-mail may contain confidential or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. We will not be liable for direct, indirect, special or consequential damages arising from alteration of the contents of this message by a third party or as a result of any virus being passed on or as of transmission of this e-mail in general.

opa114

unread,
Jan 7, 2015, 11:12:22 AM1/7/15
to jna-...@googlegroups.com
I've done it with: new String(byteArray);

and yeah i'm not the best programmer but now i have to deal with it. particularly JNA is complete new to me and not so easy to understand.
But is it a crime to ask questions?? i think a forum or something is there for asking
and discussing whether the questions are profound or simple...

Kustaa Nyholm

unread,
Jan 7, 2015, 1:17:27 PM1/7/15
to jna-...@googlegroups.com
Hi,

I tried not to offend you but apparently did not succeed in it, my bad.

Of course it is ok to ask question, simple or complex, but after 
a series of questions most of which can be answered by googling
and reading documents plus some basic programming strategies
I think it warrants a small comment to like I did.

If your problem here is strange characters then the first
thing to do is to look at those bytes and to see what those
bytes are and do they respond to any characters in 
your charset. This should raise the idea, hey, what character
set is this. Or if you had read the documentation for String(byteArray)
that also should have rang a bell about the characters sets.
And this should lead you to the solution. Also I would
expect that the function you are trying to call has some
documentation that describes the characters set used.

So to me this suggested that instead doing your own homework
you had the knee jerk reaction to ask it here on the list,
which is fine, except it may turn some people from helping
you.

Sorry if I offended you or misinterpreted you.

cheers Kusti

--
Kustaa Nyholm
Research Manager, Software
Research and Technology Division
PLANMECA OY
Asentajankatu 6
00880 HELSINKI
FINLAND

Please note our new telephone and fax numbers!
Tel: +358 20 7795 572 (direct)
Fax: +358 20 7795 676



From: opa114 <opa...@gmail.com>
Reply-To: "jna-...@googlegroups.com" <jna-...@googlegroups.com>
Date: Wed, 7 Jan 2015 18:12:22 +0200
To: "jna-...@googlegroups.com" <jna-...@googlegroups.com>
Subject: Re: Reading real Value from Structure Object

--
You received this message because you are subscribed to the Google Groups "Java Native Access" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

opa114

unread,
Jan 7, 2015, 1:37:21 PM1/7/15
to jna-...@googlegroups.com
Hi,

thanks for the tip to read the bytes. i will read about it and try it. So thanks for your advice.

You don't offended or misinterpreted me. But it was just so over as it was forbidden to ask questions, whether the questions are simple or complex. It's all good :)

Timothy Wall

unread,
Jan 7, 2015, 10:59:53 PM1/7/15
to jna-...@googlegroups.com
Pointer.get[Wide]String() exists for this purpose. You can optionally provide the native encoding if you know it.

There also exists Native.toString(byte[]) for converting a NUL-terminated C string (byte array) into a Java String.
> --
> You received this message because you are subscribed to the Google Groups "Java Native Access" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
> <Unbenannt.PNG>

opa114

unread,
Jan 8, 2015, 6:53:31 AM1/8/15
to jna-...@googlegroups.com
thanks again Timothy. but this time i solved it by myself, but thanks! :)
Reply all
Reply to author
Forward
0 new messages