바이너리 코드에서 문자열을 숨기는 방법은 무엇입니까?
때때로 바이너리 (실행 가능) 파일에서 문자열을 숨기는 것이 유용합니다. 예를 들어 바이너리에서 암호화 키를 숨기는 것이 좋습니다.
"숨기기"라고하면 컴파일 된 바이너리에서 문자열을 찾기가 더 어려워집니다.
예를 들어 다음 코드는 다음과 같습니다.
const char* encryptionKey = "My strong encryption key";
// Using the key
컴파일 후 데이터 섹션에 다음과 같은 실행 파일이 생성됩니다.
4D 79 20 73 74 72 6F 6E-67 20 65 6E 63 72 79 70 |My strong encryp|
74 69 6F 6E 20 6B 65 79 |tion key |
비밀 문자열을 쉽게 찾고 수정할 수 있음을 알 수 있습니다.
문자열을 숨길 수 있습니다 ...
char encryptionKey[30];
int n = 0;
encryptionKey[n++] = 'M';
encryptionKey[n++] = 'y';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 's';
encryptionKey[n++] = 't';
encryptionKey[n++] = 'r';
encryptionKey[n++] = 'o';
encryptionKey[n++] = 'n';
encryptionKey[n++] = 'g';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 'e';
encryptionKey[n++] = 'n';
encryptionKey[n++] = 'c';
encryptionKey[n++] = 'r';
encryptionKey[n++] = 'y';
encryptionKey[n++] = 'p';
encryptionKey[n++] = 't';
encryptionKey[n++] = 'i';
encryptionKey[n++] = 'o';
encryptionKey[n++] = 'n';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 'k';
encryptionKey[n++] = 'e';
encryptionKey[n++] = 'y';
…하지만 좋은 방법은 아닙니다. 더 좋은 아이디어가 있습니까?
추신 : 단순히 비밀을 숨기는 것이 단호한 공격자에게는 효과가 없다는 것을 알고 있지만, 아무것도없는 것보다 훨씬 낫습니다.
또한 비대칭 암호화에 대해 알고 있지만이 경우에는 허용되지 않습니다. Blowfish 암호화를 사용하고 암호화 된 데이터를 서버로 전달하는 기존 애플리케이션을 리팩토링하고 있습니다 (서버가 동일한 키로 데이터를 해독 함).
내가 할 수없는 내가 이전 버전과의 호환성을 제공해야하기 때문에 암호화 알고리즘을 변경합니다. 내가 할 수없는 경우에도 암호화 키를 변경합니다.
pavium의 답변 에 대한 주석에서 언급했듯이 두 가지 선택이 있습니다.
- 열쇠 확보
- 복호화 알고리즘 보안
안타깝게도 코드 내에 키와 알고리즘을 모두 포함해야한다면 둘 다 비밀이 아니므로 모호함을 통한 보안 의 (훨씬 더 약한) 대안이 남게됩니다 . 즉, 언급했듯이 실행 파일 내에서 둘 중 하나 또는 둘 다를 숨길 수있는 현명한 방법이 필요합니다.
여기에 몇 가지 옵션이 있지만 암호화 모범 사례에 따르면이 중 어느 것도 진정으로 안전 하지 않으며 각각의 단점 이 있다는 점을 기억해야합니다 .
- 일반적으로 코드 내에 나타나는 문자열로 키를 위장하십시오. 한 가지 예
printf()
는 숫자, 문자 및 구두점이있는 경향이 있는 문의 형식 문자열입니다 . - 시작시 코드 또는 데이터 세그먼트의 일부 또는 전부를 해시 하고이를 키로 사용합니다. (키가 예기치 않게 변경되지 않도록하려면 이에 대해 약간 영리해야합니다!) 이것은 실행될 때마다 코드의 해시 된 부분을 확인하는 잠재적으로 바람직한 부작용이 있습니다.
- 예를 들어 네트워크 어댑터의 MAC 주소를 해싱하여 시스템에 고유 한 (및 내부에서 일정한) 항목 에서 런타임에 키를 생성합니다 .
- 다른 데이터에서 바이트를 선택하여 키를 만듭니다. 정적 또는 글로벌 데이터가있는 경우, 유형에 관계없이 (의
int
,char
, 등 ),가 (물론, 0이 아닌 값으로) 초기화 것 후 각 변수 내에서 어딘가에서 바이트를 가지고 그 변경 전에.
문제 해결 방법을 알려주십시오!
편집 : 기존 코드를 리팩토링한다고 댓글을 달았으므로 반드시 키를 직접 선택할 수는 없다고 가정합니다. 이 경우 2 단계 프로세스를 따르십시오. 위의 방법 중 하나를 사용하여 키 자체를 암호화 한 다음 해당 키를 사용 하여 사용자 데이터를 해독합니다.
긴 답변 죄송합니다.
귀하의 답변은 절대적으로 정확하지만 문제는 문자열을 숨기고 멋지게하는 방법이었습니다.
나는 그런 방식으로 그것을했다 :
#include "HideString.h"
DEFINE_HIDDEN_STRING(EncryptionKey, 0x7f, ('M')('y')(' ')('s')('t')('r')('o')('n')('g')(' ')('e')('n')('c')('r')('y')('p')('t')('i')('o')('n')(' ')('k')('e')('y'))
DEFINE_HIDDEN_STRING(EncryptionKey2, 0x27, ('T')('e')('s')('t'))
int main()
{
std::cout << GetEncryptionKey() << std::endl;
std::cout << GetEncryptionKey2() << std::endl;
return 0;
}
HideString.h :
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#define CRYPT_MACRO(r, d, i, elem) ( elem ^ ( d - i ) )
#define DEFINE_HIDDEN_STRING(NAME, SEED, SEQ)\
static const char* BOOST_PP_CAT(Get, NAME)()\
{\
static char data[] = {\
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH_I(CRYPT_MACRO, SEED, SEQ)),\
'\0'\
};\
\
static bool isEncrypted = true;\
if ( isEncrypted )\
{\
for (unsigned i = 0; i < ( sizeof(data) / sizeof(data[0]) ) - 1; ++i)\
{\
data[i] = CRYPT_MACRO(_, SEED, i, data[i]);\
}\
\
isEncrypted = false;\
}\
\
return data;\
}
HideString.h에서 가장 까다로운 줄은 다음과 같습니다.
BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH_I(CRYPT_MACRO, SEED, SEQ))
선에서 벗어나도록하겠습니다. 코드 :
DEFINE_HIDDEN_STRING(EncryptionKey2, 0x27, ('T')('e')('s')('t'))
BOOST_PP_SEQ_FOR_EACH_I (CRYPT_MACRO, SEED, SEQ)시퀀스 생성 :
( 'T' ^ ( 0x27 - 0 ) ) ( 'e' ^ ( 0x27 - 1 ) ) ( 's' ^ ( 0x27 - 2 ) ) ( 't' ^ ( 0x27 - 3 ) )
BOOST_PP_SEQ_ENUM (BOOST_PP_SEQ_FOR_EACH_I (CRYPT_MACRO, SEED, SEQ))일으키다:
'T' ^ ( 0x27 - 0 ), 'e' ^ ( 0x27 - 1 ), 's' ^ ( 0x27 - 2 ), 't' ^ ( 0x27 - 3 )
그리고 마지막으로,
DEFINE_HIDDEN_STRING(EncryptionKey2, 0x27, ('T')('e')('s')('t'))
일으키다:
static const char* GetEncryptionKey2()
{
static char data[] = {
'T' ^ ( 0x27 - 0 ), 'e' ^ ( 0x27 - 1 ), 's' ^ ( 0x27 - 2 ), 't' ^ ( 0x27 - 3 ),
'\0'
};
static bool isEncrypted = true;
if ( isEncrypted )
{
for (unsigned i = 0; i < ( sizeof(data) / sizeof(data[0]) ) - 1; ++i)
{
data[i] = ( data[i] ^ ( 0x27 - i ) );
}
isEncrypted = false;
}
return data;
}
"내 강력한 암호화 키"의 데이터는 다음과 같습니다.
0x00B0200C 32 07 5d 0f 0f 08 16 16 10 56 10 1a 10 00 08 2.]......V.....
0x00B0201B 00 1b 07 02 02 4b 01 0c 11 00 00 00 00 00 00 .....K.........
답변 해 주셔서 감사합니다!
- 코드 골프 문제로 게시
- J로 작성된 솔루션을 기다리십시오.
- 앱에 J 인터프리터 삽입
코드에서 암호를 숨기는 것은 모호한 보안입니다. 실제로는 거의 가지고 있지 않지만 어느 정도 보호 수준이 있다고 생각하기 때문에 해 롭습니다. 확보 할 가치가있는 것이 있다면 제대로 확보 할 가치가 있습니다.
추신 : 실제 해커에게는 작동하지 않는다는 것을 알고 있지만 아무것도없는 것보다 훨씬 낫습니다 ...
실제로 많은 상황에서 보안이 취약한 것보다 나은 것은 없습니다. 적어도 당신은 당신이 어디에 서 있는지 정확히 알고 있습니다. 내장 된 암호를 피하기 위해 "진짜 해커"가 될 필요는 없습니다.
편집 :이 댓글에 응답 :
키 쌍에 대해 알고 있지만이 경우에는 허용되지 않습니다. Blowfish 암호화를 사용하는 기존 애플리케이션을 리팩토링합니다. 서버 및 서버에 전달 된 암호화 된 데이터는 데이터를 해독합니다. 이전 버전과의 호환성을 제공해야하므로 암호화 알고리즘을 변경할 수 없습니다.
보안에 대해 전혀 신경 쓰지 않는 경우 이전 버전과의 호환성을 유지하는 것은 내장 된 암호에 취약 해 지도록하는 정말 나쁜 이유입니다. 안전하지 않은 보안 체계와의 하위 호환성을 깨는 것은 좋은 일입니다.
길거리 아이들이 당신이 현관 열쇠를 매트 아래에두고 있다는 사실을 알게되었지만 할아버지가 그곳에서 찾을 것으로 기대하기 때문에 계속 그렇게하는 것과 같습니다.
귀하의 예제는 문자열을 전혀 숨기지 않습니다. 문자열은 여전히 출력에서 일련의 문자로 표시됩니다.
문자열을 난독화할 수있는 다양한 방법이 있습니다. 간단한 대체 cypher 가 있거나 결과가 다음 문자의 연산 등에 적용되는 각 문자 (예 : XOR)에 대해 수학 연산을 수행 할 수 있습니다.
목표는 문자열처럼 보이지 않는 데이터로 끝나는 것입니다. 예를 들어 대부분의 서양 언어로 작업하는 경우 대부분의 문자 값은 32-127 범위에 있습니다. 따라서 목표는 다음과 같습니다. 작업이 대부분 그 범위를 벗어나게 하여주의를 끌지 않습니다.
이것은 중앙역 근처의 네덜란드 암스테르담에서 자전거를 잠금 해제 한 상태로 두는 것만 큼 안전합니다. (깜박이면 사라졌습니다!)
애플리케이션에 보안을 추가하려는 경우 모든 보호 체계가 실패하므로 처음부터 실패 할 수 있습니다. 해커가 필요한 정보를 찾는 것을 더 복잡하게 만드는 것뿐입니다. 그래도 몇 가지 트릭 :
*) 문자열이 바이너리에 UTF-16으로 저장되어 있는지 확인하십시오.
*) 문자열에 숫자와 특수 문자를 추가합니다.
*) 문자열 대신 32 비트 정수 배열을 사용하십시오! 각각을 문자열로 변환하고 모두 연결하십시오.
*) GUID를 사용하여 바이너리로 저장하고 사용할 문자열로 변환합니다.
그리고 미리 정의 된 텍스트가 정말로 필요한 경우이를 암호화하고 암호화 된 값을 바이너리에 저장하십시오. 해독 할 키가 앞서 언급 한 옵션 중 하나 인 런타임에서 해독합니다.
해커가 이와 다른 방식으로 애플리케이션을 크래킹하는 경향이 있다는 사실을 알고 있어야합니다. 암호화 전문가조차도 무언가를 안전하게 보관할 수 없습니다. 일반적으로 사용자를 보호하는 유일한 방법은 해킹 비용에 비해 해커가 코드를 해킹하여 얻을 수있는 이익입니다. (이러한 비용은 많은 시간이 소요되는 경우가 많지만 애플리케이션을 해킹하는 데 1 주일이 걸리고 다른 것을 해킹하는 데 2 일이 걸린다면 다른 공격을받을 가능성이 더 높습니다.)
댓글에 대한 답장 : UTF-16은 문자 당 2 바이트이므로 모든 문자 사이에 추가 바이트가 있기 때문에 바이너리 덤프를 보는 사용자가 인식하기가 더 어렵습니다. 그래도 단어를 볼 수 있습니다. UTF-32는 문자 사이에 더 많은 공간을 추가하기 때문에 더 좋습니다. 그런 다음 문자 당 6 비트 구성표로 변경하여 텍스트를 약간 압축 할 수도 있습니다. 4 개의 문자마다 3 개의 숫자로 압축됩니다. 그러나 이것은 당신을 2x26 글자, 10 자리, 그리고 아마도 64 문자를 얻기 위해 공백과 점으로 제한 할 것입니다.
a의 사용 GUIDGUID를 텍스트 형식이 아닌 바이너리 형식으로 저장하면 실용적입니다. GUID는 길이가 16 바이트이며 임의로 생성 될 수 있습니다. 따라서 암호로 사용되는 GUID를 추측하기가 어렵습니다. 그러나 여전히 일반 텍스트를 보내야하는 경우 GUID를 "3F2504E0-4F89-11D3-9A0C-0305E82C3301"과 같은 문자열 표현으로 변환 할 수 있습니다. (또는 "7QDBkvCA1 + B9K / U0vrQx1A =="로 Base64로 인코딩됩니다.) 그러나 사용자는 코드에서 일반 텍스트를 볼 수 없으며, 임의의 데이터 만 볼 수 있습니다. 하지만 GUID의 모든 바이트가 임의적 인 것은 아닙니다. GUID에 숨겨진 버전 번호가 있습니다. 하지만 GUID를 사용하는 것은 암호화 목적에 가장 적합한 옵션은 아닙니다. MAC 주소 또는 의사 난수로 계산되므로 합리적으로 예측 가능합니다. 그래도 쉽게 생성하고 저장, 변환 및 사용하기 쉽습니다. 해커가 보안을 깨기 위해 다른 트릭을 찾으려고하기 때문에 무언가를 더 길게 만들어도 가치가 더해지지는 않습니다. 바이너리 분석에 더 많은 시간을 투자 할 의향이 있는지에 대한 질문 일뿐입니다.
일반적으로 애플리케이션을 안전하게 유지하는 가장 중요한 것은 관심있는 사람의 수입니다. 아무도 당신의 응용 프로그램에 관심이 없다면 아무도 그것을 해킹하지 않을 것입니다. 5 억 명의 사용자를 보유한 최고의 제품이되면 애플리케이션이 한 시간 내에 크랙됩니다.
나는 한때 비슷하게 어색한 위치에 있었다. 바이너리에 있어야하지만 일반 텍스트가 아닌 데이터가 있습니다. 내 솔루션은 나머지 프로그램처럼 보이게 만드는 매우 간단한 구성표를 사용하여 데이터를 암호화하는 것이 었습니다. 문자열을 가져와 모든 문자를 ASCII 코드 (3 자리 숫자를 얻기 위해 필요에 따라 0으로 채움)로 변환 한 다음 3 자리 코드의 시작과 끝에 임의의 숫자를 추가하는 프로그램을 작성하여 암호화했습니다. . 따라서 문자열의 각 문자는 암호화 된 문자열에서 5 자 (모든 숫자)로 표시되었습니다. 해당 문자열을 상수로 응용 프로그램에 붙여 넣은 다음 문자열을 사용해야 할 때 결과를 해독하여 필요한 작업을 수행하기에 충분한 시간 동안 변수에 저장했습니다.
따라서 예를 들어 '내 강력한 암호화 키'는 '207719121310329211541116181145111157110071030703283101101109309926114151216611289116161056811109110470321510787101511213'이됩니다. 그런 다음 암호화 키가 필요할 때 디코딩하되 프로세스를 실행 취소합니다.
확실히 방탄은 아니지만 나는 그것을 목표로하지 않았습니다.
암호화 기술은 중요한 데이터 를 바이너리 파일에 숨기지 않고 안전하게 보호 할 수있을만큼 강력 합니다.
아니면 무언가가 숨겨져 있다는 사실 을 가장 하기 위해 바이너리 파일을 사용하려는 생각 입니까?
그것은 스테 가노 그래피 라고 불릴 것 입니다.
클라이언트-서버 애플리케이션입니다! 클라이언트 자체에 저장하지 마십시오. 해커가 분명히 볼 수있는 곳입니다. 대신 (새 클라이언트에만 해당) 추가 서버 기능 (HTTPS를 통해)을 추가하여이 비밀번호를 검색하십시오. 따라서이 암호는 클라이언트 디스크에 도달하지 않아야합니다.
보너스로 나중에 서버를 고치는 것이 훨씬 쉬워집니다. 매번 다른 클라이언트 별 시간 제한 암호를 보내십시오. 새 클라이언트에서 더 긴 암호를 허용하는 것을 잊지 마십시오.
C의 경우 https://github.com/mafonya/c_hide_strings를 확인 하십시오.
C ++의 경우 :
class Alpha : public std::string
{
public:
Alpha(string str)
{
std::string phrase(str.c_str(), str.length());
this->assign(phrase);
}
Alpha c(char c) {
std::string phrase(this->c_str(), this->length());
phrase += c;
this->assign(phrase);
return *this;
}
};
이를 사용하려면 Alpha 및 다음을 포함하십시오.
Alpha str("");
string myStr = str.c('T').c('e').c('s').c('t');
따라서 mystr은 이제 "Test"이고 문자열은 이진 문자열 테이블에서 숨겨집니다.
간단한 인코딩을 사용하여 문자열을 인코딩 할 수 있습니다 (예 : xor 바이너리 01010101 포함). 물론 실제 보호는 없지만 string
.
암호화 키를 반대로 ( "yek noitpyrcne gnorts yM") 저장 한 다음 코드에서 반대로 (String.Reverse)하면 암호화 키의 텍스트에 대한 바이너리를 통한 단순 검색이 방지됩니다.
그러나 여기에있는 다른 모든 포스터의 요점을 반복하면 보안 측면에서 사실상 아무것도 달성 할 수 없습니다.
여기에 그들이 설명한 예가 있습니다. 그러나 이것은 "해커"인 사람에 의해 상당히 간단하게 깨질 것이지만 16 진 편집기로 꼬마를 막을 것입니다. 내가 제공 한 예제는 단순히 값 80을 추가하고 여기에서 인덱스를 부분 추적 한 다음 문자열을 다시 만듭니다. 이진 파일에 이것을 저장할 계획이라면 문자열을 byte [] 배열로 변환하는 많은 방법이 있습니다.
앱에서이 작업을 수행하면 제가 사용한 "수학"을 좀 더 복잡하게 만들 것입니다.
그것은, 취소하려면 그것의 일반 텍스트로 저장되지 않도록 저장하기 전에 그 이해하지 않는 .... 당신은 문자열을 암호화합니다. 암호화 된 텍스트가 변경되지 않을 경우 릴리스에 암호화 기능을 포함하지 않는 경우 해독 기능 만 있습니다. 따라서 문자열을 해독하려면 파일을 읽은 다음 콘텐츠를 해독합니다. 즉, 문자열은 일반 텍스트 형식으로 파일에 저장되지 않습니다.
물론 암호화 된 문자열을 응용 프로그램에 상수 문자열로 저장하고 필요할 때 암호를 해독하고 문자열의 크기와 변경 빈도에 따라 문제에 맞는 것을 선택할 수도 있습니다.
string Encrypted = EncryptMystring("AAbbBb");
string Decrypted = DecryptMystring(Encrypted);
string DecryptMystring(string RawStr)
{
string DecryptedStr = "";
for (int i = 0; i < RawStr.Length; i++)
{
DecryptedStr += (char)((int)RawStr[i] - 80 + i);
}
return DecryptedStr;
}
string EncryptMystring(string RawStr)
{
string EncryptedStr = "";
for (int i = 0; i < RawStr.Length; i++)
{
EncryptedStr += (char)((int)RawStr[i] + 80 - i);
}
return EncryptedStr;
}
그 목적으로 개발 한 C ++ 라이브러리를 사용할 수 있습니다 . 구현하기 훨씬 더 간단한 또 다른 기사 는 2017 년 9 월 최고의 C ++ 기사로 선정되었습니다 . 문자열을 숨기는 더 간단한 방법은 TinyObfuscate를 참조하십시오 .
암호를 정적 char 배열에 할당하고이 함수에 대한 포인터를 반환하는 함수를 만듭니다. 그런 다음 난독 화 프로그램을 통해이 기능을 실행하십시오.
프로그램이 잘 작동한다면. 프로그램 바이너리를 검사하기 위해 16 진 편집기를 사용하여 일반 텍스트 암호를 읽을 수 없습니다. (적어도 어셈블리 언어를 리버스 엔지니어링하지 않고서는 안됩니다. 그렇게하면 시간을 낭비 할 것이없는 범죄 적으로 미친 해커를 제외하고는 "문자열"이나 16 진 편집기로 무장 한 모든 스크립트 꼬마들이 중지됩니다.)
I think you want to make it look like instructions, your example of
x[y++]='M'; x[y++]='y'; ...
Would do just that, the long sequence of repeated instructions with a little variation may stand out and that would be bad, the byte in question may get encoded in the instruction as is and that would be bad, so perhaps the xor method, and perhaps some other tricks to make that long section of code not stand out, some dummy function calls perhaps. Depends on your processor as well, ARM for example it is real easy to look at binary data and pick out the instructions from the data and from there (if you are looking for a default key) to possibly pick out what might be the key because it is data but is not ascii and attack that. Likewise a block of similar instructions with the immediate field varying, even if you have the compiler xor the data with a constant.
I wonder if after first obscuring it like others have mentioned, you could embed your string in an assembly block to try and make it look like instructions. You could then have an "if 0" or "goto just_past_string_assembly" to jump over the "code" which is really hiding your string. This would probably require a bit more work to retrieve the string in code (a one-time coding cost), but it might prove to be a bit more obscure.
Encrypt the encryption key with another code. Show an image of the other code to the user. Now the user has to enter the key that he sees (like a captcha, but always the same code). This makes it also impossible for other programs to predict the code. Optionally you can save a (salted) hash of the code to verify the input of the user.
I suggest m4.
Store you string with macros like
const string sPassword = _ENCRYPT("real password");
Before build, expand macros to encrypted string with m4, so your code look like
const string sPassword = "encrypted string";
Decrypt in runtime environment.
Here's a perl script to generate obfuscated c-code to hide a plaintext password from "strings" program.
obfuscate_password("myPassword123");
sub obfuscate_password($) {
my $string = shift;
my @c = split(//, $string);
push(@c, "skip"); # Skip Null Terminator
# using memset to clear this byte
# Add Decoy Characters
for($i=0; $i < 100; $i++) {
$ch = rand(255);
next if ($ch == 0);
push(@c, chr($ch));
}
my $count1 = @c;
print " int x1, x2, x3, x4;\n";
print " char password[$count1];\n";
print " memset(password, 0, $count1);\n";
my $count2 = 0;
my %dict = ();
while(1) {
my $x = int(rand($count1));
$y = obfuscate_expr($count1, $x);
next if (defined($dict{$x}));
$dict{$x} = 1;
last if ($count2+1 == $count1);
if ($c[$x] ne "skip") {
#print " $y\n";
print " $y password[x4] = (char)" . ord($c[$x]) . ";\n";
}
$count2++;
}
}
sub obfuscate_expr($$) {
my $count = shift;
my $target = shift;
#return $target;
while(1) {
my $a = int(rand($count*2));
my $b = int(rand($count*2));
my $c = int(rand($count*2));
next if (($a == 0) || ($b == 0) || ($c == 0));
my $y = $a - $b;
#print "$target: $y : $a - $b\n";
if ($y == $target) {
#return "$a - $b + $c";
return "x1=$a; x2=$b; x3=$c; x4=x1-x2+x3; x5= +=x4;";
}
}
}
참고URL : https://stackoverflow.com/questions/1356896/how-to-hide-a-string-in-binary-code
'IT Share you' 카테고리의 다른 글
내 빌드의 일부로 Xml Serialization 어셈블리 생성 (0) | 2020.11.19 |
---|---|
Eclipse에서 Ant 스크립트에 대한 DTD 경고를 비활성화 하시겠습니까? (0) | 2020.11.19 |
사람들이 앱을 무료로 다운로드 할 수 있도록 프로모션 / 쿠폰 코드를 제공하는 방법이 있나요? (0) | 2020.11.18 |
Xcode 4.2는 시뮬레이터를 중지 한 후 매번 main.m으로 점프합니다. (0) | 2020.11.18 |
기본 스타일을 기반으로 스타일을 만드는 방법은 무엇입니까? (0) | 2020.11.18 |