반응형

출처: http://ememomo.tistory.com/36


/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text;

/**
 * When an object of a type is attached to an Editable, its methods will
 * be called when the text is changed.
 */
public interface TextWatcher extends NoCopySpan {
    /**
     * This method is called to notify you that, within <code>s</code>,
     * the <code>count</code> characters beginning at <code>start</code>
     * are about to be replaced by new text with length <code>after</code>.
     * It is an error to attempt to make changes to <code>s</code> from
     * this callback.
     */
    public void beforeTextChanged(CharSequence s, int start,
                                  int count, int after);
    /**
     * This method is called to notify you that, within <code>s</code>,
     * the <code>count</code> characters beginning at <code>start</code>
     * have just replaced old text that had length <code>before</code>.
     * It is an error to attempt to make changes to <code>s</code> from
     * this callback.
     */
    public void onTextChanged(CharSequence s, int start, int before, int count);

    /**
     * This method is called to notify you that, somewhere within
     * <code>s</code>, the text has been changed.
     * It is legitimate to make further changes to <code>s</code> from
     * this callback, but be careful not to get yourself into an infinite
     * loop, because any changes you make will cause this method to be
     * called again recursively.
     * (You are not told where the change took place because other
     * afterTextChanged() methods may already have made other changes
     * and invalidated the offsets.  But if you need to know here,
     * you can use {@link Spannable#setSpan} in {@link #onTextChanged}
     * to mark your place and then look up from here where the span
     * ended up.
     */
    public void afterTextChanged(Editable s);
}


TextWatcher 인터페이스를 보면 beforeTextChanged / onTextChanged /  afterTextChanged 함수를 오버라이딩 하여야 한다.

각각의 함수는 이름을 보면 대충 언제 구동되는지 알 수 있을 것이다. 

이 인터페이스를 이용해서 입력값에 대한 실시간 변화를 감지해 낼 수 잇다. 예를 들어 가격을 입력하는 창이라던지, 글자를 

입력하는 창에서 조건을 걸어 검사를 할때 유용하게 사용 할 수 있다. 

이번예제는 TextWatcher 인터페이스를 이용해서 글자수를 제한 해 보는 예제이다. 

하나의 입력창이 있고 , 그 입력창을 글자수를 실시간으로 반영 하며, 50자 이상일때 입력을 제한하는 Toast 메시지를 띄우는 

예제이다.

화면을 살펴 보면 


이런식의 예제이다. 이를 응용하면 가격표에 자동으로 , 표시를 추가하는등의 함수도 작성 할 수 있다.

쓰는 법은 간단하니 코드를 살펴 보자. 


main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical"
 android:background="#ffffff"
 android:gravity="center"
 >
 <LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal">
  <TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginLeft="9dip"
   android:layout_marginTop="10dip" />
  <TextView
   android:id="@+id/review_length"
   android:layout_marginTop="15dip"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:paddingRight="5dip"
   android:layout_marginLeft="240dip"
   android:text="0/50자" />
 </LinearLayout>
 <EditText
  android:id="@+id/estimate_review_content"
  android:layout_marginLeft="8dip"
  android:layout_marginTop="1dip"
  android:maxLength="50"
  android:padding="7dip"
  android:layout_width="200dip"
  android:layout_height="75dip" />
</LinearLayout>



Strudy_0522.java

package com.tistory.ememomo;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class Strudy_0522 extends Activity implements TextWatcher{
    
 private EditText   review_content;
    private TextView  review_length;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        review_content     = (EditText) findViewById(R.id.estimate_review_content);
        review_length     = (TextView) findViewById(R.id.review_length);
        review_content.addTextChangedListener(this);
    }
    
    @Override
 public void afterTextChanged(Editable s) {
  
 }
 @Override
 public void beforeTextChanged(CharSequence s, int start, int count,
   int after) {
  
 }
 @Override
 public void onTextChanged(CharSequence s, int start, int before, int count) {
  
  if(s.length() >= 50)
  {
   Toast.makeText(Strudy_0522.this, "글은 50자 까지 입력 가능합니다.", Toast.LENGTH_SHORT).show();
  }
  review_length.setText( s.length() + "/50자");
 }
}



EditText 입력창에 addTextChangedListener 리스너를 달아 주고 그 리스너를 이용하는건 TextView에다 넘겨주었다.

내가 처리한곳은 onTextChanged 함수 내에서 처리 했지만, 입력받기 전 중 후로 처리를 할 수 있으니 잘 살펴 보길 바란다.

반응형
반응형

출처 - http://blog.naver.com/PostView.nhn?blogId=sukuns&logNo=70114459329


에디트 텍스트 안의 글자 수를 셀때 가장 중요한 역할을 하는 것은 바로 TextWatcher라는 인터페이스이다

 

에디트텍스트는 사용자가 입력한 문자열의 상태가 바뀌는 것을 에디트텍스트 밖으로 알리기 위해 TextWatcher 객체를 addTextChangedListener()메서드의 인자로 사용한다.

 

...(생략)..

TextWatch watch = new TextWatcher(){

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after){

 CharSequence s : 현재 에디트텍스트에 입력된 문자열을 담고 있다.

 int start : s 에 저장된 문자열 내에 새로 추가될 문자열의 위치값을 담고있다.

 int count : s 에 담긴 문자열 가운데 새로 사용자가 입력할 문자열에 의해 변경될 문자열의 수가 담겨있다.

  int after : 새로 추가될 문자열의 수

}

@Override

public void onTextChanged(CharSequence s, int start, int before, int count){

 CharSequence s : 사용자가 새로 입력한 문자열을 포함한 에디트텍스트의 문자열이 들어있음

 int start : 새로 추가된 문자열의 시작 위치의 값 

int before : 새 문자열 대신 삭제된 기존 문자열의 수가 들어 있다

int count : 새로 추가된 문자열의 수가 들어있다.

}

@Override

public void afterTextChanged(Editable s){}

...(생략)..

Edittext editext = (EditText)findViewById(R.id.edittext);

edittext.addTextChangedListener(watch);

 

}

 

상위 코드가 실행되면 에디트 텍스트 문자 입력 상태가 변경될 때마다 beforeTextChanged().

onTextChanged(),afterTextChanged() 메서드를 순서대로 하나씩 호출한다.

즉, 사용자가 키보드에서 글자 한나를 누른 뒤에 손가락을 떼면 그 사이에 아래와 같은 순서를 거쳐서 글자 하나가 입력된다.

 

예 :

abcde 라는 문자열이 있다.

 이때 cde를 선택한다음

abcde

키보드에서 t를 찾아 누르면 에디트텍스트 내 문자열은 다음과같이 

abt 로 변한다

beforeTextChanged()

CharSequence s : abcde (에디트 텍스트에 들어있던 문자열

int start : (abced에서 변경될 텍스트가 c에서 시작하므로 start 값은 2 이다. 참고로 첫 문자열 a 는 0, b는 1)

int count : 3 (cde를 선택했으므로 cde의 길이는 3)

int after : 1(t가 입력되었으므로 t의 길이 1)

 

onTextChanged()

CharSequence s : abt (병경된 후 에디트 텍스트 내의 문자열 abt)

int start : 2(t는 a와 b다음이므로  위치 값은 2)

int before : 3(처음 abced에서 cde가 대신에 t 가 들어왔으므로 ced의 길이인3)

int count : 1 (새로 추가되었으므로 t의 길이 1)

반응형
반응형

https://drive.google.com/folderview?id=0B7rtSe_PH_fTWDQ0RC1DeWVoVUE&usp=sharing

반응형
반응형

계산기 쪼물딱 거리기


목적: 계산기를 이리저리 만져보면서 리버싱 스킬 향상 및 동작원리 파악


목표:  프로그래머라면 계산기를 사용할때 HEX 값을 자주 사용한다. 하지만 계산기를 작동 시키면 Default로 되어 있는 값은 DEC이다. 이 Default 값을 HEX 값으로 바꾸어 보자.



기본적인 계산기 Default 값 


계산기를 올리디버거로 열어서 해당 루틴 찾아보기


  Search for -> All intermodular calls 에서 찾아보자



     이 많은 함수 중에 어떤것이 저 함수일까?? 조금 찾아보면 Check 관련 함수들이 나와 있다. 해당 Dec에 체크가 되어 있으니 저 함수중에 우리가 바꿔야 할 함수가 있을 것이다.


음.. Check 로 시작되는 함수중에 있을것 같은데.. 이럴땐 구글링이 쵝5~ 구글링 고고싱


CheckMenuItem()

http://msdn.microsoft.com/ko-kr/library/windows/desktop/ms647619(v=vs.85).aspx


CheckMenuRadioItem()

http://msdn.microsoft.com/ko-kr/library/windows/desktop/ms647621(v=vs.85).aspx


CheckRadioButton(핸들, 시작 라디오 버튼, 끝 라디오 버튼, 체크 할 라디오 버튼)

http://msdn.microsoft.com/en-us/library/windows/desktop/bb761877(v=vs.85).aspx



구글링을 해보니 맨 마지막에 있는 것이 약간 냄새가 난다 킁킁 


CheckRadioButton()에 BreakPoint(F2)를 걸고 실행 해보자


스택을 보면 다음과 같다.


구글링한 내용으로 해당 스택을 분석해 보면 IDfirst(시작 라디오 버튼) 313 이고, IDlast(끝 라디오 버튼) 316이다. 또한 체크 되어 있는 라디오 버튼인 IDcheck가 314에 해당한다.


다시 계산기로 돌아와서, 해당 사항을 비교해보면 


 

HEX있는 곳이 시작 점(313 )으로 가정하고 보면 Dec가 체크 되어 있는 곳이(314)로 두 번째이고 마지막 Bin이 316이라고 추측해볼 수 있다.


이 추측이 맞는지 한번 확인 하는 작업을 해보자.



스택에 있는 IDcheck 값을 임시로 315로 바꾸어 보았다.


수정 후 실행을 해보면 다음과 같이 Oct에 체크되어 있는것을 볼 수 있다.


이로써 위의 추측이 사실이라는 것을 증명하였다.


그러면 이제 계산기 코드를 패칭해 보자.

일단 CheckRadioButton() 함수로 가보자



001AD4B3에서 IDcheck값에 ESI를 넣어 주고 있는데 ESI에 들어있는 값이 어디서 왔는지 찾아보면

001AD4AF에서 mov을 통해 값이 들어간다는 것을 알 수 있다.


대입하는 내용을 보면 다음과 같다.


0013E5E8에 있는 값을 가지고 온다는 것을 알 수 있다. 


그렇다면!!!! 0013E5E8로 고고싱 ~_~



리틀엔디언 형식때문에 3A 01로 되어 있는 것을 볼 수 있다.


이 값을 HEX체크 박스가 있는 시작점(313)으로 바꿔주면 될것이다. 313은 십진수고 HEX값으로 바꿔주면 139이다. 

그러면 리틀엔디언 형식을 고려하여 39 01 이렇게 넣어주면 될것으로 보인다.


더 조사하다 보니 이미 39 01 이 이미 입력되어 있다는 것을 파악하였다. 





001AD4AF에서 [EBP+10] = 13A으로 되어있는데 [EBP+10]을 [EBP+8]로 수정 하면 내가 원하는 139을 가지고 올 수 있다.




수정한 후 Copy to exeutable -> All selections을 선택 후 save files로   실행파일을 저장하자


이제 해당 실행 파일을 확인해보자 !_!




굿굿 잘 들어 왔군..


이것으로 글을 마치겠습니다. 


반응형

+ Recent posts