2011-04-08

Quick and dirty script to compile binutils with all targets

Yeah, yeah, I know you're not supposed to compile binutils in situ and whatnot, but I need a fully functional objdump/objcopy for testing stuff and I don't have all day.

The following script, when ran from the binutils-x.yz directory will compile binutils with all the targets. Worked 8 years ago, works today. Who'd want more?
#!/bin/sh

ROOT=`pwd`

for i in libiberty intl bfd opcodes binutils
do
cd $ROOT/$i
./configure --enable-targets=all --disable-nls
make -j4
done
You'll get a bunch of warnings about configure: WARNING: unrecognized options: --enable-targets, --disable-nls for some of the subprojects, but you can ignore them. Once you're done, you should have a nice objdump executable in the binutils/ directory, which, when poked with option -i should report something like this:
/usr/src/binutils-2.23.51-1/binutils/objdump: supported targets: pe-i386 a.out.adobe a.out-zero-big a.out-mips-little epoc-pe-arm-big epoc-pe-arm-little epoc-pei-arm-big epoc-pei-arm-little pe-arm-wince-big pe-arm-wince-little pei-arm-wince-big pei-arm-wince-little coff-arm-big coff-arm-little a.out-arm-netbsd pe-arm-big pe-arm-little pei-arm-big pei-arm-little b.out.big b.out.little elf32-avr elf32-bfin elf32-bfinfdpic elf32-big elf32-bigarc elf32-bigarm elf32-bigarm-symbian elf32-bigarm-vxworks elf32-bigmips elf32-bigmips-vxworks elf32-bigmoxie elf32-bignios2 elf32-cr16 elf32-cr16c elf32-cris elf32-crx elf32-d10v elf32-d30v elf32-dlx elf32-epiphany elf32-fr30 elf32-frv elf32-frvfdpic elf32-h8300 elf32-hppa-linux elf32-hppa-netbsd elf32-hppa elf32-i370 elf32-i386-freebsd elf32-i386-nacl elf32-i386-sol2 elf32-i386-vxworks elf32-i386 elf32-i860-little elf32-i860 elf32-i960 elf32-ip2k elf32-iq2000 elf32-lm32 elf32-little elf32-littlearc elf32-littlearm elf32-littlearm-symbian elf32-littlearm-vxworks elf32-littlemips elf32-littlemips-vxworks elf32-littlemoxie elf32-littlenios2 elf32-m32c elf32-m32r elf32-m32rle elf32-m32r-linux elf32-m32rle-linux elf32-m68hc11 elf32-m68hc12 elf32-m68k elf32-m88k elf32-mcore-big elf32-mcore-little elf32-mep elf32-metag elf32-microblaze elf32-mn10200 elf32-mn10300 elf32-mt elf32-msp430 elf32-openrisc elf32-or32 elf32-pj elf32-pjl elf32-powerpc elf32-powerpc-vxworks elf32-powerpcle elf32-powerpc-freebsd elf32-rl78 elf32-rx-be elf32-rx-be-ns elf32-rx-le elf32-s390 elf32-sh elf32-shbig-fdpic elf32-shbig-linux elf32-sh-fdpic elf32-shl elf32-shl-symbian elf32-sh-linux elf32-shl-nbsd elf32-shl-vxworks elf32-sh-nbsd elf32-sh-vxworks elf32-sparc elf32-sparc-sol2 elf32-sparc-vxworks elf32-spu elf32-tic6x-be elf32-tic6x-le elf32-tilegx-be elf32-tilegx-le elf32-tilepro elf32-tradbigmips elf32-tradlittlemips elf32-tradbigmips-freebsd elf32-tradlittlemips-freebsd elf32-us-cris elf32-v850 elf32-v850-rh850 elf32-vax elf32-xc16x elf32-xgate elf32-xstormy16 elf32-xtensa-be elf32-xtensa-le pe-powerpc pei-powerpc pe-powerpcle pei-powerpcle a.out-cris ecoff-bigmips ecoff-biglittlemips ecoff-littlemips coff-go32 coff-go32-exe coff-h8300 coff-h8500 a.out-hp300hpux a.out-i386 a.out-i386-bsd coff-i386 a.out-i386-freebsd a.out-i386-lynx coff-i386-lynx msdos a.out-i386-netbsd i386os9k pei-i386 coff-i860 coff-Intel-big coff-Intel-little ieee coff-m68k coff-m68k-un a.out-m68k-netbsd coff-m68k-sysv coff-m88kbcs a.out-m88k-mach3 a.out-m88k-openbsd mach-o-be mach-o-le mach-o-fat mach-o-i386 pe-mcore-big pe-mcore-little pei-mcore-big pei-mcore-little pe-mips pei-mips a.out-newsos3 nlm32-i386 nlm32-powerpc nlm32-sparc coff-or32-big a.out-pc532-mach a.out-ns32k-netbsd a.out-pdp11 pef pef-xlib ppcboot aixcoff-rs6000 coff-sh-small coff-sh coff-shl-small coff-shl pe-shl pei-shl som coff-sparc a.out-sparc-little a.out-sparc-linux a.out-sparc-lynx coff-sparc-lynx a.out-sparc-netbsd a.out-sunos-big sym a.out-tic30 coff-tic30 coff0-beh-c54x coff0-c54x coff1-beh-c54x coff1-c54x coff2-beh-c54x coff2-c54x coff-tic80 a.out-vax-bsd a.out-vax-netbsd a.out-vax1k-netbsd versados vms-libtxt coff-w65 coff-we32k coff-z80 coff-z8k elf32-am33lin srec symbolsrec verilog tekhex binary ihex
/usr/src/binutils-2.23.51-1/binutils/objdump: supported architectures: aarch64 alpha alpha:ev4 alpha:ev5 alpha:ev6 arc arc5 base arc6 arc7 arc8 arm armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te xscale ep9312 iwmmxt iwmmxt2 avr avr:1 avr:2 avr:25 avr:3 avr:31 avr:35 avr:4 avr:5 avr:51 avr:6 avr:101 avr:102 avr:103 avr:104 avr:105 avr:106 avr:107 bfin cr16 cr16c cris crisv32 cris:common_v10_v32 crx d10v d10v:ts2 d10v:ts3 d30v dlx epiphany32 epiphany16 fr30 frv tomcat simple fr550 fr500 fr450 fr400 fr300 h8300 h8300h h8300s h8300hn h8300sn h8300sx h8300sxn h8500 hppa1.1 hppa2.0w hppa2.0 hppa1.0 i370:common i370:360 i370:370 i386 i386:x86-64 i386:x64-32 i8086 i386:intel i386:x86-64:intel i386:x64-32:intel i860 i960:core i960:ka_sa i960:kb_sb i960:mc i960:xa i960:ca i960:jx i960:hx ia64-elf64 ia64-elf32 ip2022ext ip2022 iq2000 iq10 k1om k1om:intel l1om l1om:intel lm32 m16c m32c m32r m32rx m32r2 m68hc11 m68hc12 m68hc12 m9s12x m9s12xg m68k m68k:68000m68k:68008 m68k:68010 m68k:68020 m68k:68030 m68k:68040 m68k:68060 m68k:cpu32 m68k:fido m68k:isa-a:nodiv m68k:isa-a m68k:isa-a:mac m68k:isa-a:emac m68k:isa-aplus m68k:isa-aplus:mac m68k:isa-aplus:emac m68k:isa-b:nousp m68k:isa-b:nousp:mac m68k:isa-b:nousp:emac m68k:isa-b m68k:isa-b:mac m68k:isa-b:emac m68k:isa-b:float m68k:isa-b:float:mac m68k:isa-b:float:emac m68k:isa-c m68k:isa-c:mac m68k:isa-c:emac m68k:isa-c:nodiv m68k:isa-c:nodiv:mac m68k:isa-c:nodiv:emac m68k:5200 m68k:5206e m68k:5307 m68k:5407 m68k:528x m68k:521x m68k:5249 m68k:547x m68k:548x m68k:cfv4e m88k:88100 MCore mep h1 c5 metag MicroBlaze mips mips:3000 mips:3900 mips:4000 mips:4010 mips:4100 mips:4111 mips:4120 mips:4300 mips:4400 mips:4600 mips:4650 mips:5000 mips:5400 mips:5500 mips:5900 mips:6000 mips:7000 mips:8000 mips:9000 mips:10000 mips:12000 mips:14000 mips:16000 mips:16 mips:mips5 mips:isa32 mips:isa32r2 mips:isa64 mips:isa64r2 mips:sb1 mips:loongson_2e mips:loongson_2f mips:loongson_3a mips:octeon mips:octeon+ mips:octeon2 mips:xlr mips:micromips mmix mn10200 mn10300 am33 am33-2 moxie msp:14 msp:11 msp:110 msp:12 msp:13 msp:14msp:15 msp:16 msp:21 msp:31 msp:32 msp:33 msp:41 msp:42 msp:43 msp:44 ms1 ms1-003 ms2 nios2 ns32k:32032 ns32k:32532 openrisc or32 pdp11 powerpc:common powerpc:common64 powerpc:603 powerpc:EC603e powerpc:604 powerpc:403 powerpc:601 powerpc:620 powerpc:630 powerpc:a35 powerpc:rs64ii powerpc:rs64iii powerpc:7400 powerpc:e500 powerpc:e500mc powerpc:e500mc64 powerpc:MPC8XX powerpc:750 powerpc:titan powerpc:vle powerpc:e5500 powerpc:e6500 rs6000:6000 rs6000:rs1 rs6000:rsc rs6000:rs2 rl78 rx rx s390:31-bit s390:64-bit score7 score3 sh sh2 sh2e sh-dsp sh3 sh3-nommu sh3-dsp sh3e sh4 sh4a sh4al-dsp sh4-nofpu sh4-nommu-nofpu sh4a-nofpu sh2a sh2a-nofpu sh2a-nofpu-or-sh4-nommu-nofpu sh2a-nofpu-or-sh3-nommu sh2a-or-sh4 sh2a-or-sh3e sh5 sparc sparc:sparclet sparc:sparclite sparc:v8plus sparc:v8plusa sparc:sparclite_le sparc:v9 sparc:v9a sparc:v8plusb sparc:v9b spu:256K tms320c30 tms320c4x tms320c3x tms320c54x tic6x tic80 tilegx tilegx32 tilepro v850 (using old gcc ABI) v850e3v5 (using old gcc ABI) v850e2v4 (using old gcc ABI) v850e2v3 (using old gcc ABI) v850e2 (using old gcc ABI) v850e1 (using old gcc ABI) v850e (using old gcc ABI) v850-rh850 v850e3v5 v850e2v4 v850e2v3 v850e2 v850e1 v850e vax w65 we32k:32000 xstormy16 xtensa xc16x xc16xl xc16xs xgate z80-any z80-strict z80 z80-full r800 z8001 z8002

2011-04-06

32 bit apps, Windows x64 and the System32 directory

While adding a hidden magic key feature to Zadig, that deletes the libusb-1.0 DLLs that are installed by the libusbK driver in System32\ and SysWOW64\ (when you are developing for both libwdi and libusb, the multiplication of libusb DLLs becomes a major issue), I found that a 32 bit Zadig application running on x64 Windows would not see the libusb-1.0.dll residing in System32\.

The reason for that is that, from a 32 bit app perspective, Windows maps SysWOW64\ (the directory that, as its name does NOT indicate, contains 32 bit binaries) to System32\, and therefore trying to access the actual System32\ (the directory that contains 64 bit binaries) using %WINDIR%\System32.

If for any reason you want to access the actual System32\ directory from a 32 bit application running on Windows x64, you have to use Sysnative (eg: C:\Windows\Sysnative).

2011-04-01

Enabling the Issuer Statement button on a Windows certificate

You may have seen a few of these certificates where clicking on the "Issuer Statement" button brings you to a specific webpage, usually a "Certification Practice Statement", or CPS, on the issuer's webserver. Maybe you've wondered how you could achieve the same on certificates you generate? Well, wonder no more.

It basically all boils down to adding a CPS Policy Identifier in the Certificate Policies field, and the Windows PKI API provides everything you need to do so:

  DWORD dwSize;
  CERT_POLICY_QUALIFIER_INFO certPolicyQualifier;
  CERT_POLICY_INFO certPolicyInfo = { "1.3.6.1.5.5.7.2.1", 1, &certPolicyQualifier };
  CERT_POLICIES_INFO certPolicyInfoArray = { 1, &certPolicyInfo };
  CHAR szCPSName[] = "http://cps-page.yourserver.com";
  CERT_NAME_VALUE certCPSValue;
  CERT_EXTENSION certExtension;
  CERT_EXTENSIONS certExtensionsArray = { 1, &certExtension };

  // Set the CPS Certificate Policies field - this enables the "Issuer Statement" button on the cert
  certCPSValue.dwValueType = CERT_RDN_IA5_STRING;
  certCPSValue.Value.cbData = sizeof(szCPSName);
  certCPSValue.Value.pbData = (BYTE*)szCPSName;
  if ( (!CryptEncodeObject(X509_ASN_ENCODING, X509_NAME_VALUE, (LPVOID)&certCPSValue, NULL, &dwSize))
    || ((pbCPSNotice = (BYTE*)malloc(dwSize)) == NULL)
    || (!CryptEncodeObject(X509_ASN_ENCODING, X509_NAME_VALUE, (LPVOID)&certCPSValue, pbCPSNotice, &dwSize)) ) {
    printf("could not setup CPS\n");
    goto out;
  }

  certPolicyQualifier.pszPolicyQualifierId = szOID_PKIX_POLICY_QUALIFIER_CPS;
  certPolicyQualifier.Qualifier.cbData = dwSize;
  certPolicyQualifier.Qualifier.pbData = pbCPSNotice;
  if ( (!CryptEncodeObject(X509_ASN_ENCODING, X509_CERT_POLICIES, (LPVOID)&certPolicyInfoArray, NULL, &dwSize))
    || ((pbPolicyInfo = (BYTE*)malloc(dwSize)) == NULL)
    || (!CryptEncodeObject(X509_ASN_ENCODING, X509_CERT_POLICIES, (LPVOID)&certPolicyInfoArray, pbPolicyInfo, &dwSize)) ) {
    printf("could not setup Certificate Policies\n");
    goto out;
  }

  certExtension.pszObjId = szOID_CERT_POLICIES;
  certExtension.fCritical = FALSE;
  certExtension.Value.cbData = dwSize;
  certExtension.Value.pbData = pbPolicyInfo;

  // Call CertCreateSelfSignCertificate() with certExtensionsArray as the last parameter or something...
  (...)

out:
  // Cleanup...
  if (pbCPSNotice != NULL) free(pbCPSNotice);
  if (pbPolicyInfo != NULL) free(pbPolicyInfo);
For a real-life example of the above, as well as the setting of other certificate properties such as the Enhanced Key Usage or an URL in the Subject Alternative Name, you may want to have a look at the LGPL pki.c from libwdi, and our CreateSelfSignedCert() function there.

Oh, and we pretty much rewrote basic LPGL redistributable versions of the MakeCat/Inf2Cat, MakeCert, CertMgr and Signtool WDK utilities, so if you need them, there's here as well. For additional details, look here