“JAVA” 标签页面:

  • Android中Java编写的APK使用apktool反编译并修改smali

    今天装了某个游戏,游戏中有“商店”,可以用金币购买相关物品。而获得金币的途径,是用人民币购买(1元100只)或者安装该公司的其他应用(安装3款得一点点)。

    这显然不科学啊!

    当然,程序在我机子上,我们当然能够用科学的手段来对付不科学的游戏货币商城制度。

    1、使用apktool进行反编译,得到smali的字节码

    假设游戏安装文件为my_game.apk,我们将把它反编译到mygame目录下。

    这里下载apktool和对应的dependencies,把apktool和对应的dependencies加压缩到一起,并将该文件夹添加到path环境变量中。我在使用Windows系统,这时候apktool的解压文件夹有以下内容:

    aapt.exe

    apktool.bat

    apktool.jar

    然后对my_game.apk进行反编译,运行命令:

    apktool d my_game.apk mygame

    可以看到apktool将游戏反编译到mygame文件夹中。其中的smali就是对应的字节码。

    2、修改smali字节码

    关于smali字节码的寄存器可以参考这里,类型、函数和成员可以参考这里,操作符号可以参考这里

    当然,由于程序已经混淆,所以不能从文件名和包名中猜测相关信息。这时候有好几个办法定位到要修改的地方。如调试设断点,在这里有教程。还可以通过资源和字符串定位,这是我现在使用的方法,因为我的调试环境还没搭好……

    我注意到,某一个与购买相关的按钮图片的id编号为“0x7f020093”,于是在smali中搜索,最后在某个文件夹,也就对应Java的某个包中找到g.smali,这个文件包含了字符串“0x7f020093”。然后,点击购买时,会提示“金币不足,无法购买”,这是文本信息。也就是说,可以在g.smali中搜索该字符串,或者字符串子串来进行程序上下文的定位。当然,直接搜索中文字符串是一无所获的,因为反编译器将中文以utf8的裸编码格式表现。这时候在g.smali中搜索“\u91d1\u5e01\u4e0d\u8db3,\u65e0\u6cd5\u8d2d\u4e70”,找到详细位置!具体代码片段如下:

    sget-object v0, La/f/c;->s:La/a/b/g;

    iget-object v9, v0, La/a/b/g;->j:Ld/a/b;

    iget v10, p2, La/d/n;->f:I

    iget v0, v9, Ld/a/b;->v:I

    if-ge v0, v10, :cond_0

    invoke-static {}, Lcom/gale/manager/f;->a()Lcom/gale/manager/f;

    move-result-object v0

    const-string v1, "\u91d1\u5e01\u4e0d\u8db3,\u65e0\u6cd5\u8d2d\u4e70"

    invoke-virtual {v0, v1}, Lcom/gale/manager/f;->a(Ljava/lang/String;)V

    :goto_0
    return-void

    :cond_0
    neg-int v0, v10

    iput v0, v9, Ld/a/b;->x:I

    需要关注的是“if-ge”这句,意思是如果v0大于等于v10,则跳到cond_0执行,否则显示“金币不足,无法购买”并返回。

    我们可以直接将“if-ge”改成“if-le”解决问题,不过这时金币会在购买后变负数,说不定会把游戏crash。所以,更好的修改方法如下:

        sget-object v0, La/f/c;->s:La/a/b/g;

        iget-object v9, v0, La/a/b/g;->j:Ld/a/b;

        iget v10, p2, La/d/n;->f:I

        iget v0, v9, Ld/a/b;->v:I

        if-ge v0, v10, :cond_0
        goto/16 :cond_0

        :goto_0
        return-void

        :cond_0
        move v0, v10

        iput v0, v9, Ld/a/b;->x:I

    意思是,即使当前金币小于购买所需金币,也跳到条件成立的地方执行。另外,执行时会将玩家的金币数加上所需金币的相反数,即“neg-int v0, v10”,将其改为“move v0, v10”就可以每次都把玩家的金币数加上所需金币数。最终效果则是,即使金币不足也可以购买,并且越买钱越多。

    3、打包、签名和安装修改后的apk

    修改完了,就可以打包回apk了。执行以下命令:

    apktool b mygame

    在mygame目录下的dist在会看到打包好的apk。

    当然,现在一般是无法安装的,因为apk还没有签名。下面就来签名。签名需要keystore文件,我已经有专用的keystore了,如果还没有,请参阅这里进行生成。

    执行以下命令为重新编译的my_game.apk签名:

    jarsigner -verbose -keystore creke.keystore my_game.apk Alias_name

    最后,在安装到手机前,需要把手机中的已有版本先卸载,因为如果签名不同,是不能覆盖安装的,会提示“应用程序未安装”错误。

    4、其他

    Windows下的aapt似乎不能对非本地磁盘进行读写,比如我原来在内存盘中进行操作,apktool总是提示aapt出错,不能打包apk。后来放到本地磁盘中进行才一切正常。

    最后说一句,好的游戏从来不会用奇怪的货币和商城来吸引玩家或者玩家的钱财。

    2012.05.09 / 9 条评论 / 10,990 次点击 / 分类: 所谓技术

  • PHP与JAVA使用AES128位加密通信

    本来JAVA和JSP之间加密通信好好的,相同的函数,相同的处理,不会有其他大问题。不过有时候就是蛋疼啊,于是就有了PHP与JAVA间使用AES进行加密通信。

    PHP的AES128位由mcrypt模块提供,称为MCRYPT_RIJNDAEL_128。

    JAVA的AES默认就是128位的。

    加密模式有好几种,不同的语言不同的库支持的情况不同。这里选择的是安全且通用的CBC模式。

    至于padding,这是最头疼的问题,因为PHP的padding与Java的padding不一样。如果使用NoPadding,则默认又用不了CBC模式。所以,最好的解决方法是自己padding——在原文末尾加上若干个空格,使原文凑齐16的倍数的长度。当然,原文末尾也可能是空格结束啊,那怎么办?没办法,只有强制原文末尾加上一个换行。这样子,每次解密后,将最右边的换行以及其右边的空格裁剪掉,就得到原文了。

    另外,为了兼容,在加密和解密时,需要将内容转换成16进制的字符数组。这样一来,即使加密/解密的内容不是普通文本,而是二进制数据,也可以轻松传送啦。

    JAVA方面

    初始化代码:

            try {
                cipherEnc = Cipher.getInstance("AES/CBC/NoPadding");
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            } catch (NoSuchPaddingException ex) {
                ex.printStackTrace();
            }
            try {
                cipherDec = Cipher.getInstance("AES/CBC/NoPadding");
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            } catch (NoSuchPaddingException ex) {
                ex.printStackTrace();
            }
    
            key = new SecretKeySpec(keyStr.getBytes(), "AES");
            iv = new IvParameterSpec(ivStr.getBytes());

    加密解密及其核心函数:

        public static String padRight(String s, int n) {
            return String.format("%1$-" + n + "s", s);
        }
    
        public static String padLeft(String s, int n) {
            return String.format("%1$#" + n + "s", s);
        }
        
        public String encrypt(SecretKeySpec enc_key, IvParameterSpec enc_iv, String str){
            byte[] ret = null;
            
            try {
                cipherEnc.init(Cipher.ENCRYPT_MODE, enc_key, enc_iv);
                ret = cipherEnc.doFinal(padRight(str,
                        ((int)Math.ceil(str.length() / 16.0))*16).getBytes());
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
            
            return byteArray2HexString(ret);
        }
        
        /*
         * str is Hex String
         */
        public String decrypt(SecretKeySpec dec_key, IvParameterSpec dec_iv, String str){
            byte[] ret = null;
            
            try {
                cipherDec.init(Cipher.DECRYPT_MODE, dec_key, dec_iv);
                ret = cipherDec.doFinal(hexString2ByteArray(str));
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
            
            try {
    			return new String(ret, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			return null;
    		}
        }
    
        static final char[] HEX_CHAR_TABLE = {
            '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
        };
    
        public static String byteArray2HexString(byte[] b) {
            if (b == null) {
                return null;
            }
            final StringBuilder hex = new StringBuilder(2 * b.length);
            for (final byte by : b) {
                hex.append(HEX_CHAR_TABLE[(by & 0xF0) >> 4]).append(HEX_CHAR_TABLE[(by & 0x0F)]);
            }
            return hex.toString();
        }
        
        public static byte[] hexString2ByteArray(String s) {
            if (s == null) {
                return null;
            }
            byte high, low;
            int len = s.length() / 2;
            byte[] b = new byte[len];
            for(int i=0, k=0; i<len; i++, k+=2)
            {
                high = (byte) (Character.digit(s.charAt(k), 16) & 0x0F);
                low = (byte) (Character.digit(s.charAt(k+1), 16) & 0x0F);
                b[i] = (byte) ((high<<4) | low);
            }
            
            return b;
        }

    PHP方面

    加密解密部分及其核心函数

    	static function encrypt($enc_key, $enc_iv, $data){
    		$pad = str_pad($data, ceil(strlen($data)/16.0)*16, " ");
    		
    		$method = MCRYPT_RIJNDAEL_128;
    		$mode = MCRYPT_MODE_CBC;
    		$td = mcrypt_module_open($method, '', $mode, '');
    		mcrypt_generic_init ( $td , $enc_key , $enc_iv);
    		$encrypt = mcrypt_generic($td, $pad);
    		mcrypt_generic_deinit($td);
    		mcrypt_module_close($td);
    		
    		return bin2hex($encrypt);
    	}
    	
    	static function decrypt($dec_key, $dec_iv, $data){
    		$method = MCRYPT_RIJNDAEL_128;
    		$mode = MCRYPT_MODE_CBC;
    		$td = mcrypt_module_open($method, '', $mode, '');
    		mcrypt_generic_init ( $td , $dec_key , $dec_iv);
    		$decrypt = mdecrypt_generic($td, hex2bin($data));
    		mcrypt_generic_deinit($td);
    		mcrypt_module_close($td);
    	
    		return $decrypt;
    	}
    
    if(!function_exists('hex2bin'))
    {
    	/**
    	 * Converts the hex representation of data to binary
    	 *
    	 * http://www.php.net/manual/en/function.hex2bin.php
    	 *
    	 * @param   string  $str        Hexadecimal representation of data
    	 *
    	 * @return  string              Returns the binary representation of the given data
    	 */
    	function hex2bin($data)
    	{
    		return pack("H*" , $data);
    	}
    }

    就是这样啦。什么?不懂怎么用?那就看看AES的文献,看看Java和PHP的文档再说吧。

    2012.03.08 / 6 条评论 / 3,966 次点击 / 分类: 所谓技术

  • JAVA中将PrivateKey和X509Certificate对象保存为OpenSSL等程序可用的标准格式

    我将两个个对象存进了ca.cert中,第一个是CA的私钥,第二个是CA的证书。

    现在需要将ca.cert中的CA私钥和证书读取出来,并保存为OpenSSL等程序可识别的标准格式。

    以下是代码:

    import java.io.*;
    import java.security.*;
    import java.security.spec.*;
    import java.security.cert.X509Certificate;
    import java.util.*;
    import sun.misc.BASE64Encoder;
    import org.bouncycastle.asn1.x509.BasicConstraints;
    import org.bouncycastle.asn1.x509.X509Extensions;
    import org.bouncycastle.jce.X509Principal;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.x509.X509V3CertificateGenerator;
    import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
    
    public class ExportKeys
    {
    	public static void main(String args[])
    	{
    		X509Certificate caCert = null;
        PrivateKey caPriKey = null;
        PublicKey caPubKey = null;
        
        BASE64Encoder encoder = null;
    		
    		try
    		{
    			FileInputStream caCertFis = new FileInputStream("ca.cert");
    			ObjectInputStream caCertOis = new ObjectInputStream(caCertFis);
    			caPriKey = (PrivateKey) caCertOis.readObject();
    			caCert = (X509Certificate) caCertOis.readObject();
    			caPubKey = caCert.getPublicKey();
    			
    			caCertOis.close();
    			caCertFis.close();
    		} catch (Exception ex)
    		{
    			ex.printStackTrace();
    		}
    		
    		//导出私钥
    		try
    		{
    			encoder=new BASE64Encoder();
    			String encoded=encoder.encode(caPriKey.getEncoded());
    			FileWriter fw=new FileWriter("ca.key");
    			fw.write("-----BEGIN PRIVATE KEY-----\n");
    	    fw.write(encoded);
    	    fw.write("\n");
    	    fw.write("-----END PRIVATE KEY-----");
    	    fw.close();
    	  } catch (Exception ex)
    		{
    			ex.printStackTrace();
    		}
    		
    		//导出证书
    		try
    		{
    			encoder=new BASE64Encoder();
    			String encoded=encoder.encode(caCert.getEncoded());
    			FileWriter fw=new FileWriter("ca.crt");
    			fw.write("-----BEGIN CERTIFICATE-----\n");
    	    fw.write(encoded);
    	    fw.write("\n");
    	    fw.write("-----BEGIN CERTIFICATE-----");
    	    fw.close();
    	  } catch (Exception ex)
    		{
    			ex.printStackTrace();
    		}
    	}
    }

    程序需要使用bouncycastle库来操作X509证书(即CA证书),下载地址在这里

    编译命令和执行命令是:

    编译:

    javac -cp .;bcprov-ext-jdk15-145.jar ExportKeys.java

    执行:

    java -cp .;bcprov-ext-jdk15-145.jar ExportKeys

    就是这样,完毕。

    2011.08.29 / 2 条评论 / 1,270 次点击 / 分类: 所谓技术

  • JAVA动态生成兼容浏览器的HTTPS(SSL)证书

    JAVA自带的SSL以及X509库只能使用SSL证书,不能生成SSL证书。因此我们使用“Bouncy Castle”这个算法库来实现SSL证书的生成。然后使用X509KeyManager来构建符合浏览器规范的SSL证书链,以便自建代理服务器时,信任该CA就可以浏览HTTPS内容而不会有安全提醒。

    浏览器生成的CA,使用X509的V3版。V3版和V1版的主要不同是可以生成扩展字段。详细信息可以参考Bouncy Castle的WIKI上面的解释。参考了burpsuite,发现CA的扩展字段需要Subject Key Identifier,再加上Basic Constraints声明是CA及最大中间CA数即可兼容大部分主流浏览器。

    注意一点,就是Windows系统的证书验证似乎只检查公钥私钥,根证书使用相同的密钥对每次动态生成都可以通过信任CA的认证;而Firefox则严格很多,需要把CA保存下来,每次都使用同样的CA才能匹配信任列表中的对应CA。

    生成密钥对:

                KeyPairGenerator caKeyPairGen = KeyPairGenerator.getInstance("RSA", "BC");
                caKeyPairGen.initialize(1024, new SecureRandom());
                KeyPair keypair = caKeyPairGen.genKeyPair();
    
                caPriKey = keypair.getPrivate();
                caPubKey = keypair.getPublic(); 

    生成CA:

        public static X509Certificate createAcIssuerCert(
            PublicKey       pubKey,
            PrivateKey      privKey)
            throws Exception
        {
            X509V3CertificateGenerator  v3CertGen = new X509V3CertificateGenerator();
            //
            // signers name 
            //
            String  issuer = "CN=My CA, OU=My CA, O=My, L=My, ST=AMy, C=CN";
    
            //
            // subjects name - the same as we are self signed.
            //
            String  subject = issuer;
    
            //
            // create the certificate - version 3
            //
    
            v3CertGen.setSerialNumber(BigInteger.valueOf(0x1234ABCDL));
            v3CertGen.setIssuerDN(new X509Principal(issuer));
            v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 30*aDay));
            v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + 36500*aDay));
            v3CertGen.setSubjectDN(new X509Principal(subject));
            v3CertGen.setPublicKey(pubKey);
            v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
    
            // Is a CA
            v3CertGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));
    
            v3CertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey));
    
            X509Certificate cert = v3CertGen.generateX509Certificate(privKey);
    
            cert.checkValidity(new Date());
    
            cert.verify(pubKey);
    
            return cert;
        }

    使用CA签发网站证书:

        public static X509Certificate createClientCert(
            PublicKey       pubKey,
            PrivateKey      caPrivKey,
            PublicKey       caPubKey,
            String host)
            throws Exception
        {
            X509V3CertificateGenerator  v3CertGen = new X509V3CertificateGenerator();
            //
            // issuer
            //
            String  issuer = "CN=My CA, OU=My CA, O=My, L=My, ST=My, C=CN";
    
            //
            // subjects name table.
            //
            Hashtable                   attrs = new Hashtable();
            Vector                      order = new Vector();
    
            attrs.put(X509Principal.C, "CN");
            attrs.put(X509Principal.O, "My");
            attrs.put(X509Principal.OU, "My");
            attrs.put(X509Principal.CN, host);
    
            order.addElement(X509Principal.C);
            order.addElement(X509Principal.O);
            order.addElement(X509Principal.OU);
            order.addElement(X509Principal.CN);
    
            //
            // create the certificate - version 3
            //
            v3CertGen.reset();
    
            v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
            v3CertGen.setIssuerDN(new X509Principal(issuer));
            v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 10*aDay));
            v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + 3650*aDay));
            v3CertGen.setSubjectDN(new X509Principal(order, attrs));
            v3CertGen.setPublicKey(pubKey);
            v3CertGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
            
            X509Certificate cert = v3CertGen.generateX509Certificate(caPrivKey);
    
            cert.checkValidity(new Date());
    
            cert.verify(caPubKey);
    
            return cert;
        }

    对应的X509KeyManager每次从host_port.cert文件中读取对应的网站证书,然后加上CA证书构成证书链返回:

    public final class MyKeyManager implements X509KeyManager {
    
        private String entryname;
        private String port;
        private X509Certificate caCert;
        private X509Certificate clientCert;
        private PrivateKey privatekey;
    
        MyKeyManager(String host, String port, X509Certificate caCert) {
            this.port = port;
            this.entryname = host;
            this.caCert = caCert;
            try {
                String certFileName = host + "_" + port + ".cert";
                FileInputStream caCertFis = new FileInputStream(certFileName);
                ObjectInputStream oos = new ObjectInputStream(caCertFis);
                privatekey = (PrivateKey) oos.readObject();
                clientCert = (X509Certificate) oos.readObject();
                oos.close();
                caCertFis.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
        }
    
        public String[] getClientAliases(String string, Principal[] prncpls) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public String chooseClientAlias(String[] strings, Principal[] prncpls, Socket socket) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
        public String[] getServerAliases(String string, Principal[] prncpls) {
            return (new String[] {
                entryname
            });
        }
    
        public String chooseServerAlias(String string, Principal[] prncpls, Socket socket) {
            return entryname;
        }
    
        public X509Certificate[] getCertificateChain(String string) {
            X509Certificate x509certificates[] = new X509Certificate[2];
    
            x509certificates[0] = clientCert;
            x509certificates[1] = caCert;
    
            return x509certificates;
        }
    
        public PrivateKey getPrivateKey(String string) {
            return this.privatekey;
        }
    
    }

    使用实例:

                SSLContext sslcontext;
                sslcontext = SSLContext.getInstance("SSL");
                X509KeyManager[] x509km = new X509KeyManager[]{
                    new AsanKeyManager(host , port , KeyMaker.getCAcert())};
                sslcontext.init(x509km, null, null);
    
                SSLServerSocketFactory sslserversocketfactory = sslcontext.getServerSocketFactory();

    这样动态生成证书,只要在浏览器第一次浏览HTTPS内容时,信任该CA,以后就不会出现安全警告了。当然,真正的安全程度,靠的是你的代理程序的数据传输的安全性啦。

    2011.02.13 / 2 条评论 / 1,713 次点击 / 分类: 所谓技术

  • JAVA启航之旅(写给新手):安装配置IDE(Jcreator篇)

    JAVA启航之旅(写给新手):安装配置IDE(Jcreator篇)

    前言:
    大家学习C++时,使用的一般是VC或者C-free。偶尔有火星人用TC,偶尔由高手用VS。其实它们都集成了开发套装(编译器、解释器及库类等)和开发环境(源代码编辑器)。但是学习JAVA时,事情就没那么简单了。你要分别配置两者。
    这次,我们选择Jcreator作为IDE。针对新手。全文讲解比较详细。
    Jcreator是最接近VC和C-free的IDE,相信大家如果只是应付一下学习,只是随便抄点程序,使用Jcreator是最佳选择,而且会很快上手。

    前言:请确定你的机器已经安装并配置好了JDK。如果没有,请参照本人写的《JAVA启航之旅:安装配置JDK(JAVA SE)》

    一、下载并安装Jcreator
    前往http://www.jcreator.com/download.htm下载Jcreator。然后,安装。大家也不要执迷于汉化版了,既然已经学到了JAVA,认命吧,用英文版吧。动一下手,动一下脑子也好,对不。

    二、配置Jcreator
    首次启动Jcreator时,出现"Jcreator Setup Wizard"。建议在"User settings"中选择"Save settings in the installation directory",以防重装系统时丢失配置。下一步来到"File Associations",这是文件关联,一般默认即可。下一步来到"JDK Home Directory",这里填写JDK的安装目录,不过一般都能够自动识别,不用管。下一步来到"JDK JavaDoc Directory",这里填写JDK文档目录,一般没装,所以默认留空或自动识别,不用管,点击"Finish"

    三、注册Jcreator
    Jcreator注册后才能成为专业版,专业版相对普通版多出的功能都是很实用的,比如代码提示等等。你可以去官方网站注册,费用是单用户89美元,教育用途用户35美元。显然大家都买不起,所以深感社会主义好的我们,可以直接填写注册码。在这里,如果你是Jcreator 4.5的用户,可以:在Help――Enter Registration Details里,在Name处填写"Made By HHJ",在Key处填写"00000G-HHH22K-WTK2U6-RWFVDW-VAJMPC-EPM47D-JXA0U9-9F228N-PAK6ME"。如果你在看到本文后时光已经流逝了不知多少岁月(说不定这时MS已经倒闭了),如果你用的是比4.5更高版本,你就得上网新版本注册码了。

    四、配置Jcreator
    基本不需要配置,说了够傻瓜的。想DIY的就调一下各个视图就OK了。

    讲完了。大家使用上次的HelloDate测试一下就行。

    2009.02.18 / 暂无评论 / 1,374 次点击 / 分类: 所谓技术

  • JAVA启航之旅(写给菜鸟):安装配置JDK(JAVA SE)

    JAVA启航之旅(写给菜鸟):安装配置JDK(JAVA SE)

    写给菜鸟。

    一、安装JDK
    http://www.skycn.com/soft/52313.html下载Java SE Development Kit (JDK)。然后,安装。

    二、设置环境变量:
    右击"我的电脑"――属性——高级――环境变量。
    你可以更改"用户变量"部分,那么你的更改只能用于当前用户;你也可以更改"系统变量"部分,那么你的更改可以用于计算机所有用户。
    单击"新建",在"变量名"中输入"java_home",在"变量值"中填入你的JDK的安装路径,默认为"C:\Program Files\Java\jdk1.6.0_12"是你的JDK默认安装位置,具体根据自己的电脑作修改。大家可以看见,这个变量描述了JDK的安装位置,可以便于下面的设置。
    单击"新建","变量名"中输入"classpath",在"变量值"中填入".;%java_home%\lib;%java_home%\lib\tools.jar"。其中"."表示当前目录,后面的不难理解了。
    找到"path"变量,单击"编辑",在"变量值"的最后加上";%java_home%\bin"。如果找不到"path"变量就按照上面的方法新建path变量。
    注意:以上操作不区分大小写。

    三、测试JDK
    用记事本输入"************"之间的内容:
    ************
    import java.util.*;

    public class HelloDate
    {
    public static void main(String[] args)
    {
    System.out.println("Hello,it's:");
    System.out.println(new Date());
    }
    }
    ************
    单击"文件"――"保存",在"文件类型"中选择"所有文件(*.*)",然后在"文件名"中输入"HelloDate.java",接着把保存地点选到D盘的根目录,最后单击保存。
    然后单击"开始"――"运行"。输入"cmd",回车。这步操作是打开"命令提示符"。
    在那个黑乎乎,看着就觉得恐怖的界面中,输入"javac d:\HelloDate.java"。如果没什么不正确的提示,那么恭喜你,你可以继续输入“d:”,回车,跳转到C盘根目录,再输入"java HelloDate"。这时将会显示一句"Hello,it's:"以及当前系统时间。
    注意:以上操作区分大小写!

    到此为止,JDK安装配置完毕!有什么问题,欢迎交流!

    2009.02.17 / 暂无评论 / 486 次点击 / 分类: 所谓技术

  • 我与JAVA(一)

    我与JAVA(一)
        终于学了JAVA,3天前开始。
        选择JAVA,就等于选择不断学习。这句话没错。JAVA的语法、函数都在不断变化中,这也反映了JAVA的特点:灵活而有生命力。
        JAVA应该是个不错的选择。跨平台,安全,而且应用广。
        学到常量变量部分,遇到了一些难题,基本都解决了,感觉还行。计划月底学完基本知识,起码能学到网络编程(说不定编个挂Q工具,哈哈)。一定要实现目标!

    2007.07.11 / 暂无评论 / 288 次点击 / 分类: 随心随感